lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

There has been some active discussion regarding Lua's number type, and I
just happened to have done some surgery on 4.0b yesterday regarding this.
I'll explain what I did and why.  I'm not saying this is the best way, but
it may be helpful as a reference.

Embedded systems often have harsh constraints.  Because of this I think the
stock Lua should allow more strict control of the number types used.  Not
only the types used in the implementation, but also the interface.  And not
only for "lua numbers", but also the types used to hold opcodes, etc.  If
Lua opcodes only need 32 bits, a 32 bit type should be used.  Not a "long"
which is 64 bits on some platforms, using 2x memory.  There are ANSI-C
portable ways of determining types based on the number of bits you need.
(See's stdint.h header for example.  This is basically what
will be in the C99 standard.)

Anyway, in my specific case I had to modify Lua for the PlayStation2
platform.  This platform has hardware support for floats, but doubles are
emulated in software.  They are 10-100 times slower than floats.  A few
accidental calls to double operations (including casts) will bring your
real-time game to its knees.  There is a gcc option "-fshort-double", but it
does not resolve interface issues and especially has problems with
variable-argument functions such as printf/scanf.

So I set out to make Lua float-only, while still keeping the Lua API
backwards compatible when doubles are used.  (There are other issues for
doing integer-only so I'm not handling that case.)

1) Remove all hard-coded doubles.  In the Lua implementation there is a type
called Number, yet there are a few places in the code that still hard-code a
double.  Also in functions such as "expten", constants such as 10.0 needed
to first be assigned to a variable of type Number or casted in place.  (Note
that in "float x = 10.0", even though 10.0 is a double the cast will happen
at compile time.)  However the Lua standard library implementation uses the
Lua API so the Number typedef is not available.

2) Make the number type in the Lua API configurable.  I added a type to the
API (lua.h) called "lua_Number".  This type must be "hard coded" (that is,
you can't allow the API user to change it with a compile define, because the
library was already compiled using a certain type).  To do this I made a
lua.h template and used sed to fill in the type based on the build
configuration.  The doubles in the API were then changed to lua_Number.

In addition to lua_Number, I added one function called lua_getscanstr which
returns the string needed by scanf to read a lua_Number (such as "%f").
This was implemented as a macro, with the string being filled in on the
lua.h template.

Note that when lua_Number is set to double, the API is exactly as the stock

3) In the Lua implementation, remove the LUA_NUM_TYPE define and instead
"typedef lua_Number Number".  (Alternatively you can replace all occurances
of "Number" with "lua_Number", but I thought this would complicate merges
with future Lua releases.)

4) Now that the number type and scanf string are available from the API,
remove all hard-coded doubles from the Lua standard library implementations.

5) I added a compile define called "FLOAT_MATH".  When it is set, lmathlib.c
will redefine sin, cos, etc. to their floating point equivalents (sinf,
cosf, etc... available in many C libraries).