

I've noticed that Lua never stores floating point values inf, nan, 0.0 in bytecode (in table of constants). Example: local x = 5/4  constant 1.25 due to constant folding. local y = 1/0  constants 0, 1 and DIV instruction. local z = 0.0  constant 0.0 and UNM instruction. It seems that Lua intentionally defers possible FP errors until runtime. Why such approach was implemented?


> I've noticed that Lua never stores floating point values inf, nan, 0.0 in
> bytecode (in table of constants).
> Example:
> local x = 5/4  constant 1.25 due to constant folding.
> local y = 1/0  constants 0, 1 and DIV instruction.
> local z = 0.0  constant 0.0 and UNM instruction.
> It seems that Lua intentionally defers possible FP errors until runtime.
> Why such approach was implemented?
It is simpler and safer, and we don't think those constants are common
in performancecritical code.
NaN and 0 have problems with the unification of constants used by the
compiler: NaN is not equal to NaN, while 0 is equal to 0.
Moreoever, if needed, it is easy to redefine the macro luai_numdiv
to raise a Lua error for a zero denominator (for an hypothetical
architecture that could crash with that operation). So, we avoid
doing that operation during compile time.
 Roberto


On Wed, Jul 10, 2019 at 11:39 PM Roberto Ierusalimschy wrote:
NaN and 0 have problems with the unification of constants used by the
compiler: NaN is not equal to NaN, while 0 is equal to 0.
BTW, there is an arithmetic bug in Lua 5.1 related to this "minus zero problem"
(this bug was fixed in 5.2 by allowing 0.0 and +0.0 to exist independently in constant table)
print(0 < 1/0)  run in Lua 5.1


Egor Skriptunoff wrote:
> I've noticed that Lua never stores floating point values inf, nan, 0.0 in
> bytecode (in table of constants).
> Example:
> local x = 5/4  constant 1.25 due to constant folding.
> local y = 1/0  constants 0, 1 and DIV instruction.
> local z = 0.0  constant 0.0 and UNM instruction.
> It seems that Lua intentionally defers possible FP errors until runtime.
> Why such approach was implemented?
I don't know about Lua but when I wrote code to generate x86 assembly
off a custom bytecode, the fact that all constants were finite numbers
was very handy.

Alex


We're not speaking about binary integers as you see tham on x86. But about floating point values: and there even with the x86, you have negative values, signed infinites, and multiple NaNs. These all come from the IEEE standard (that describe them) and what is implemented in the x86 FPUs. Then these becomes values also in C/C++.
It justt happens that Lua numbers are all possible values of floating point numbers supported by the underlying C platform on which it was compiled (it may implement the "numbers" using a mix of "int" and "double" subtypes in C, this does not matter as in Lua these are still a single type, the subtypes being only internal optimizations that should not affect the identity of numbers or their precision; note that Lua does not perform strict evaluation of numbers in its VM, like what is done in Java, so it is always exposed to these values at any time in user programs).
If a Lua implementation wants to optimize the "numbers" implementation using binary integers, they can do that as long as they don't violate the identity and precision of numbers. Wehver you like them or not, negative zeroes, multiple distinct values of NaNs, the fact that even two binary identical NaNs compare as being different, the existence of underflow numbers (with the maximum negative power of 2, but with reduced precision), and the existence of at least two infinite values (possibly more, depending on the way the native FPU implements these values, with several additional bits left in the mantissa) is something you have to live with. Le jeu. 11 juil. 2019 à 20:13, Alexander Nasonov < [hidden email]> a écrit :
I don't know about Lua but when I wrote code to generate x86 assembly
off a custom bytecode, the fact that all constants were finite numbers
was very handy.

