Denormal numbers is sometimes treated as zero in Luau and arithmetic operations that results in denormal numbers results in zero

This bug only occurs in Luau; I cannot reproduce this in vanilla Lua 5.1.
This bugs occurs in both studio and in-game.
This is a bug where denormal numbers are treated as 0 when doing many arithmetic operations (addition, subtraction, multiplication, division, and exponentiation, etc) and them with them printing as 0 for the %g, %e, etc format therefore it produces the following unexpected results:

string.format ‘%g’ (which tostring on number runs under the hood) when inserted 5e-324 (which is stored as 0 00000000000 0000000000000000000000000000000000000000000000000001 in IEEE 754 double precision floating point format therefore it’s denormal):

print(string.format('%g', 5e-324))

Vanilla Lua:
image

Luau (Studio):
image

When executing 2-1023
Vanilla Lua:
image
Luau (Studio):
image

A denormal number add 0 equals to 0
image


I presume that this bug is an oversight by the developers of the Roblox engine when optimising Luau but I’m not certain.
math.frexp and string.pack (d format) doesn’t suffer from this issue and works as expected.
image

1 Like

This is not a bug, and isn’t Luau specific.

Roblox engine enables a special CPU flag (FTZ - flush to zero) that results in various operations that produce a denormal number to produce 0 instead. This flag is process-wide (or rather thread-wide I guess, but the intention is to enable it on a process level).

The reason why we enable this flag is that on many Intel CPUs, denormal numbers have catastrophic performance implications, and they can be produced naturally during computations especially in our physics engine.

“Catastrophic” isn’t just a fancy word to scare you away. On some AMD processors from the last decade, the cost of doing an arithmetic operation that results in a denormal number is 175 cycles. This is vs the usual cost of something like half a cycle - 300x slower. These can also flush the CPU pipeline, delaying all other operations. Of course not every instruction is like that and often only some numbers contain denormals, but we’ve seen significant random slowdowns because of this in our physics solver and decided to enable FTZ to fix that problem.

The reason why you can’t reproduce this in vanilla Lua interpreter is that it doesn’t set this flag. You could reproduce this before inside Roblox Lua before we switched to Luau (although there’s no way to test this since 2020 so you’ll need to trust me on that).

15 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.