Lua and numbers

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Lua and numbers

Gavin Wraith
I know that the question of numbers in Lua have been discussed
frequently in the Lua-list in the past, but I do not think this
specific question has been addressed.

As I understand it, Lua is set up to have one basic sort
of number, LUA_NUMBER, by default 'double', which is used
internally and to which other sorts of number are cast
automatically.

What I want is a somewhat different arrangement, because the
CPU I use (XScale) is not equipped with FP ops or FP
coprocessor. For that reason, I set LUA_NUMBER to int
(32 bit in my set up). However I would also like to be able
to use fp numbers (32 bit again) as a separate sort of
number (identified by presence of a decimal point in
numeric literals). I want a single, explicit, int2fp cast
function, and no implicit casting.

I can certainly see my way to modifying the sources to get this,
but before I launch myself into activity I thought that I had better
ask advice. Lots of people may have done this already. What is the best
way of getting what I want with the least discourteous hackery to the
sources as they stand?

PS. I know that implicit type conversions are very useful in awk,
and that it has become traditional to use them in scripting
languages. However, making explicit all type conversions from int to fp
(or double, or ... ) is also a useful regime in some circumstances,
so it would be nice to be able to make such a choice in luaconf.h.

--
Gavin Wraith ([hidden email])
Home page: http://www.wra1th.plus.com/
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

Asko Kauppi

Just use the "integer patch" from Wiki power patch pages.

http://lua-users.org/wiki/LuaPowerPatches

It boost Lua non-FPU performance by 33-500% (depending on application) and does not modify the
usage of Lua in any way (that is, numbers are numbers, and only internally optimized if they are not
needing FPU's).

The patch is well tested, on both NSLU2 and N770 hardware (ARM CPUs).

-asko


Lainaus Gavin Wraith <[hidden email]>:

> I know that the question of numbers in Lua have been discussed
> frequently in the Lua-list in the past, but I do not think this
> specific question has been addressed.
>
> As I understand it, Lua is set up to have one basic sort
> of number, LUA_NUMBER, by default 'double', which is used
> internally and to which other sorts of number are cast
> automatically.
>
> What I want is a somewhat different arrangement, because the
> CPU I use (XScale) is not equipped with FP ops or FP
> coprocessor. For that reason, I set LUA_NUMBER to int
> (32 bit in my set up). However I would also like to be able
> to use fp numbers (32 bit again) as a separate sort of
> number (identified by presence of a decimal point in
> numeric literals). I want a single, explicit, int2fp cast
> function, and no implicit casting.
>
> I can certainly see my way to modifying the sources to get this,
> but before I launch myself into activity I thought that I had better
> ask advice. Lots of people may have done this already. What is the best
> way of getting what I want with the least discourteous hackery to the
> sources as they stand?
>
> PS. I know that implicit type conversions are very useful in awk,
> and that it has become traditional to use them in scripting
> languages. However, making explicit all type conversions from int to fp
> (or double, or ... ) is also a useful regime in some circumstances,
> so it would be nice to be able to make such a choice in luaconf.h.
>
> --
> Gavin Wraith ([hidden email])
> Home page: http://www.wra1th.plus.com/
>
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

Gavin Wraith
In message <[hidden email]> you wrote:
 
> Just use the "integer patch" from Wiki power patch pages.

I am afraid you have either misunderstood what I wrote or not read
it carefully. I already use integers for Lua_number. What I need is two
numeric types in Lua, one for 32-bit integers and one for
32-bit floating point numbers. At the moment the sources use
only one sort of numeric type. In lua.h for example we have

#define LUA_TNIL                0
#define LUA_TBOOLEAN            1
#define LUA_TLIGHTUSERDATA      2
#define LUA_TNUMBER             3
#define LUA_TSTRING             4
#define LUA_TTABLE              5
#define LUA_TFUNCTION           6
#define LUA_TUSERDATA           7
#define LUA_TTHREAD             8

Would it be safe to add a line

#define LUA_TFLOAT              9

for the extra type, for example? Or would this clash with

const char *const luaT_typenames[] = {
  "nil", "boolean", "userdata", "number",
  "string", "table", "function", "userdata", "thread",
  "proto", "upval"
};

in ltm.c, which suggests that codes 9 and 10 are already used?
Having two 32-bit numeric types would appear to require fairly
radical rewriting of the sources. And yet I do not think it an
unreasonable thing to want on an ARM machine.

--
Gavin Wraith ([hidden email])
Home page: http://www.wra1th.plus.com/
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

Lisa Parratt
Gavin Wraith wrote:
> In message <[hidden email]> you wrote:
>  
>> Just use the "integer patch" from Wiki power patch pages.
>
> I am afraid you have either misunderstood what I wrote or not read
> it carefully.

Unless I'm mistaken the integer patch makes numbers use an integer if
they're an integer, or a real if they're not. There wouldn't be a need
for a patch if it were merely replacing numbers with integers, since
that's already a configuration option.

I don't see it as viable to patch in support for a new numeric type -
neither the language nor the implementation is designed to support it.
It would need a vast quantity of the code base to be overhauled.

--
Lisa
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

Asko Kauppi

Yes, exactly as Lisa put it.

My use of "integer patch" name was probably misleading, it really is either "non-FPU optimization
patch" or "integer optimization patch".

You can freely set it up in any combination of:
- int32 / int64
- float / double

In your situation, you'd opt for int32 and float, which both eat 32 bits.

The benefits:
- integer speed for integer operations
- integer precision throughout the int32 range
- transparent int/float conversions, but only when needed (i.e if doing 2/3, or maxint+1)

I really think this would be Your Thing for the ache. And it wouldn't shake any of the upper Lua layers,
not even Lua/C API. A bit. :)

In that way, you can compare it to the array optimization of Lua 1..N tables. The upper layers won't see
a thing.

-asko



Lainaus Lisa Parratt <[hidden email]>:

> Gavin Wraith wrote:
> > In message <[hidden email]> you
> wrote:
> >  
> >> Just use the "integer patch" from Wiki power patch pages.
> >
> > I am afraid you have either misunderstood what I wrote or not read
> > it carefully.
>
> Unless I'm mistaken the integer patch makes numbers use an integer if
> they're an integer, or a real if they're not. There wouldn't be a need
> for a patch if it were merely replacing numbers with integers, since
> that's already a configuration option.
>
> I don't see it as viable to patch in support for a new numeric type -
> neither the language nor the implementation is designed to support it.
> It would need a vast quantity of the code base to be overhauled.
>
> --
> Lisa
>
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

Gavin Wraith
In message <[hidden email]> you wrote:
 

> My use of "integer patch" name was probably misleading, it really is
> either "non-FPU optimization
> patch" or "integer optimization patch".
>
> You can freely set it up in any combination of:
> - int32 / int64
> - float / double
>
> In your situation, you'd opt for int32 and float, which both eat 32 bits.
>
> The benefits:
> - integer speed for integer operations
> - integer precision throughout the int32 range
> - transparent int/float conversions, but only when needed
> (i.e if doing 2/3, or maxint+1)

I need the 32-bit integer arithmetic for interfacing to the OS,
and that requires the integer arithmetic to be modulo 2^32. So
0xffffffff + 1 has to be zero, not some floating point number.
The floating point numbers (modelling the reals, a field
of characteristic zero) have to be kept totally separate from
integers (modelling the ring of integers modulo 2^32). There can be
no sensible coercions between between them, seeing that
there are no homomorphisms between the rings they model.

<rant - please excuse>
Programming languages tend to serve the mathematician
poorly for coping with the infinite multiplicity of meanings that
"number" can have. No doubt there are practical advantages in
having the IEEE standards, and processors that have been intensively
developed to use them, but even for modelling real arithmetic the IEEE
formats are a few among an infinity of different possibilities, some
better for particular tasks than others. Did you know that
you can have real arithmetics that are exactly associative
(which the IEEE formats are not)? Google "Abbas Edalat" to find out.
Or you can use modular arithmetic modulo a large prime; or
lazy streams of rational Moebius transformations, .... .
I am afraid that a lot of programmers tend to dismiss arithmetic as a
bothersome technical detail, and are thankful to the cram the
whole business into the IEEE's bed of Procrustes (google if this
particular kind of bed is not familiar!).
</rant>
--
Gavin Wraith ([hidden email])
Home page: http://www.wra1th.plus.com/
Reply | Threaded
Open this post in threaded view
|

Compiling Lua 5.1

Robert Hibberdine
In reply to this post by Gavin Wraith
Hi all,

I have been using Lua 5.0 successfully for a few weeks now. I compiled
5.0 so that lua used the shared libraries liblua.so and liblualib.so.
There was support in the make file to do this easily.

I have compiled and run lua 5.1 successfully but only as a staticly
linked  program. The 5.1 makefile does not seem to allow the making of
.so's. (I must confess at this point that I only look at makefiles when
I have to and therefore could have missed something)

I am assuming that there is no problem in building lua5.1 in 3 parts
(lua, liblua.so and liblualib.so) and can just make my own makefile...?

tia

Bob
Reply | Threaded
Open this post in threaded view
|

Re: Compiling Lua 5.1

Alex Queiroz
Hallo,

On 4/6/06, Robert Hibberdine <[hidden email]> wrote:
>
> I am assuming that there is no problem in building lua5.1 in 3 parts
> (lua, liblua.so and liblualib.so) and can just make my own makefile...?
>

     As of Lua 5.1, liblua and liblualib were merged. But there is no
problem building liblua as a shared library.

--
-alex
http://www.ventonegro.org/
Reply | Threaded
Open this post in threaded view
|

Re: Compiling Lua 5.1

Luiz Henrique de Figueiredo
> But there is no problem building liblua as a shared library.

Right. The standard Makefiles do not do this because the correct
incantation for building shared libraries differs from system to system,
and we do not want to rely on libtool. We do not want to open that can
of worms (having already opened other cans...). --lhf
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

Joshua Jensen
In reply to this post by Asko Kauppi
[hidden email] wrote:
> My use of "integer patch" name was probably misleading, it really is either "non-FPU optimization
> patch" or "integer optimization patch".
>  
I was curious to look at this, but I get the following:

[U:\temp]svn cat svn://slugak.dyndns.org/public/lua-patches/intopt.patch
svn: Can't connect to host 'slugak.dyndns.org': No connection could be
made because the target machine actively refused it.

This has been happening since yesterday.

Josh
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

David Jones-2
In reply to this post by Gavin Wraith

On Apr 06, 2006, at 14:43, Gavin Wraith wrote:

>
> <rant - please excuse>
> Programming languages tend to serve the mathematician
> poorly for coping with the infinite multiplicity of meanings that
> "number" can have. No doubt there are practical advantages in
> having the IEEE standards, and processors that have been intensively
> developed to use them, but even for modelling real arithmetic the IEEE
> formats are a few among an infinity of different possibilities, some
> better for particular tasks than others. Did you know that
> you can have real arithmetics that are exactly associative
> (which the IEEE formats are not)? Google "Abbas Edalat" to find out.
> Or you can use modular arithmetic modulo a large prime; or
> lazy streams of rational Moebius transformations, .... .
> I am afraid that a lot of programmers tend to dismiss arithmetic as a
> bothersome technical detail, and are thankful to the cram the
> whole business into the IEEE's bed of Procrustes (google if this
> particular kind of bed is not familiar!).
> </rant>

I appreciate that you're deliberately ranting, and I appreciate and
agree with many of your points, but what you want can be achieved with
what most computer scientists would call a datatype.

I think Lua does rather well here with userdata and tables and
metatables.  You want a model of {\bb Z}/13 ? Go make a nice metatable
and knock yourself out.

drj

Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

John D. Ramsdell-2
In reply to this post by Gavin Wraith
> From: Gavin Wraith <[hidden email]>
> Subject: Re: Lua and numbers
>
> > My use of "integer patch" name was probably misleading, it really is
> > either "non-FPU optimization
> > patch" or "integer optimization patch".

Yeah, all I want is to avoid using all floating point operations.  I
have enclosed the patch I use.  You must define LUA_NUMBER_INTEGRAL,
or you'll get the original behavior of LUA_NUMBER as a double.

John

diff -ur olua-5.1/src/lmathlib.c lua-5.1/src/lmathlib.c
--- olua-5.1/src/lmathlib.c 2005-08-26 13:36:32.000000000 -0400
+++ lua-5.1/src/lmathlib.c 2006-04-10 08:36:30.000000000 -0400
@@ -252,8 +252,10 @@
   luaL_register(L, LUA_MATHLIBNAME, mathlib);
   lua_pushnumber(L, PI);
   lua_setfield(L, -2, "pi");
+#if !defined(LUA_NUMBER_INTEGRAL)
   lua_pushnumber(L, HUGE_VAL);
   lua_setfield(L, -2, "huge");
+#endif
 #if defined(LUA_COMPAT_MOD)
   lua_getfield(L, -1, "fmod");
   lua_setfield(L, -2, "mod");
diff -ur olua-5.1/src/luaconf.h lua-5.1/src/luaconf.h
--- olua-5.1/src/luaconf.h 2006-02-10 12:44:06.000000000 -0500
+++ lua-5.1/src/luaconf.h 2006-04-10 08:43:24.000000000 -0400
@@ -488,14 +488,18 @@
 ** ===================================================================
 */
 
+#if defined LUA_NUMBER_INTEGRAL
+#define LUA_NUMBER long
+#else
 #define LUA_NUMBER_DOUBLE
 #define LUA_NUMBER double
+#endif
 
 /*
 @@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
 @* over a number.
 */
-#define LUAI_UACNUMBER double
+#define LUAI_UACNUMBER LUA_NUMBER
 
 
 /*
@@ -505,11 +509,20 @@
 @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
 @@ lua_str2number converts a string to a number.
 */
+#if defined LUA_NUMBER_INTEGRAL
+#define LUA_NUMBER_SCAN "%ld"
+#define LUA_NUMBER_FMT "%ld"
+#else
 #define LUA_NUMBER_SCAN "%lf"
 #define LUA_NUMBER_FMT "%.14g"
+#endif
 #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
 #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+#if defined LUA_NUMBER_INTEGRAL
+#define lua_str2number(s,p) strtol((s), (p), 10)
+#else
 #define lua_str2number(s,p) strtod((s), (p))
+#endif
 
 
 /*
@@ -521,8 +534,14 @@
 #define luai_numsub(a,b) ((a)-(b))
 #define luai_nummul(a,b) ((a)*(b))
 #define luai_numdiv(a,b) ((a)/(b))
+#if defined LUA_NUMBER_INTEGRAL
+#define luai_nummod(a,b) ((a)%(b))
+LUA_NUMBER luai_ipow(LUA_NUMBER, LUA_NUMBER);
+#define luai_numpow(a,b) (luai_ipow(a,b))
+#else
 #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
 #define luai_numpow(a,b) (pow(a,b))
+#endif
 #define luai_numunm(a) (-(a))
 #define luai_numeq(a,b) ((a)==(b))
 #define luai_numlt(a,b) ((a)<(b))
diff -ur olua-5.1/src/lvm.c lua-5.1/src/lvm.c
--- olua-5.1/src/lvm.c 2006-01-23 14:51:43.000000000 -0500
+++ lua-5.1/src/lvm.c 2006-04-10 08:44:41.000000000 -0400
@@ -27,6 +27,25 @@
 #include "lvm.h"
 
 
+#if defined LUA_NUMBER_INTEGRAL
+LUA_NUMBER luai_ipow(LUA_NUMBER a, LUA_NUMBER b) {
+  if (b < 0)
+    return 0;
+  else if (b == 0)
+    return 1;
+  else {
+    LUA_NUMBER c = 1;
+    for (;;) {
+      if (b & 1)
+ c *= a;
+      b = b >> 1;
+      if (b == 0)
+ return c;
+      a *= a;
+    }
+  }
+}
+#endif
 
 /* limit for table tag-method chains (to avoid loops) */
 #define MAXTAGLOOP 100
Reply | Threaded
Open this post in threaded view
|

Re: Lua and numbers

John D. Ramsdell-2
In reply to this post by Gavin Wraith
> From: [hidden email] (John D. Ramsdell)
>
> Yeah, all I want is to avoid using all floating point operations.  

I realized my patch failed to take care of difftime.  I made the
corrected patch available on the lua-users wiki.

John