7/29/2026 at 5:29:06 AM
> Everyone already knows floating-point operations are imprecise and it wouldn’t be fun to blog about.Wellll... Yes and no. And I want to nitpick "FP ops are imprecise" because it's important sometimes.
It does come up in Lua - Lua uses 64-bit double floats for everything, _even array indexing_, because they have 53 bits of mantissa and they're guaranteed to represent all 32-bit integers with 100% precision.
I just opened Lua and got `2 ^ 32 == 4294967296.0` and `2 ^ 32 + 1 == 4294967297.0`. You can store 4 billion things in a Lua table and access them with double float indexes.
The usual "0.1 + 0.2 != 0.3" is _not_ imprecision. You could dedicate 1,000 bits to a float and still find some example of a number that's trivial to represent in decimal but repeats forever in binary.
While I'm on it, fixed-point and floating-point aren't magically different. Floats work better on very big values. Fixed-points are more predictable but run out of range easily when squaring numbers. This comes in 3D math when finding the length of vectors or normalizing vectors.
The PlayStation 1 didn't have jiggly vertices and warpy textures because of fixed-point. It had jiggly vertices because its GPU didn't have subpixel-precise rendering, and it only had 16 bits of precision. It had warpy textures because it had affine texture mapping. The N64's GPU had more bits of precision and it had perspective-correct texture mapping. There's no 16-bit floating-point format that would have saved the PS1 from wobbling.
Also floats aren't the cause of T-junctions or "sparklies" that are common in 3D game levels. That will happen in any system with finite precision, and if fixed-point would fix it, we'd use fixed-point.
by ReactiveJelly
7/29/2026 at 9:38:42 AM
Thank you! I completely agree with this, floats are treated as a lot more magical than they actually are. I myself often rely on their exact guarantees for fun tricks (e.g. fast precise int<->float conversion: https://purplesyringa.moe/blog/fast-limited-range-conversion...). But while IEEE-754 is very precise, some subtleties arise when you add library functions to the mix -- many libm's and userland libraries don't guarantee 0.5 ulp precision for certain operations and don't document the guaranteed precision either, at which point you're left guessing and saying "well, I guess I should treat floats as magic in this case after all". I added "it's not imprecision" to step around this whole question.by purplesyringa
7/29/2026 at 8:19:33 AM
> Lua uses 64-bit double floats for everythingNot true in Lua >= 5.3. 64-bit signed integers are included in the number type now. And there is a math.ult function for treating them as unsigned.
And so 0x7fffffffffffffff is representable properly.
by mjmas
7/29/2026 at 8:39:51 AM
this is true but basically everyone uses LuaJIT these daysby lexicality
7/29/2026 at 6:12:55 PM
Well, I use PICO-8 LUA. Where are my double-precision floats and 64bit integers at? XDby HappMacDonald
7/29/2026 at 10:57:54 AM
Pinned several language versions ago? No they don't.by inigyou
7/29/2026 at 3:11:49 PM
Citation needed. You only need LuaJIT if performance is very important, which is not the case for many scripting purposes. I personally use Lua 5.3.by spacechild1
7/29/2026 at 7:19:31 AM
> The PlayStation 1 didn't have jiggly vertices and warpy textures because of fixed-pointIndeed modern GPUs still use fixed-point rasterizers.
by cmovq
7/29/2026 at 3:26:35 PM
> Lua uses 64-bit double floats for everything, _even array indexing_, because they have 53 bits of mantissa and they're guaranteed to represent all 32-bit integers with 100% precision.Lua 5.3 introduced a proper integer type. However, JavaScript still represents all numbers as doubles!
by spacechild1
7/29/2026 at 11:10:49 AM
> The usual "0.1 + 0.2 != 0.3" is _not_ imprecision.It _is_ imprecision. Even if you cannot represent 0.3 exactly, you can consider the closest representable number, and that is different than the sum of the closest numbers to 0.1 and 0.2 because doing all of this introduced imprecision.
by SkiFire13
7/29/2026 at 12:42:16 PM
To expand on this, the imprecision arises the moment you write 0.1 (decimal) in source code and the compiler converts it to binary; the arithmetic itself is (mostly) exact. So as long as you use numbers that look "good enough" in base-2, floats behave very reasonably. The constantly made assumption that floats are imprecise is, in this sense, a user error -- the user shouldn't have used decimals.by purplesyringa
7/29/2026 at 8:57:01 AM
> The usual "0.1 + 0.2 != 0.3" is _not_ imprecision.Correct. That’s using the wrong base. Decimal floating point doesn’t have that problem.
by brewmarche
7/29/2026 at 10:06:42 AM
On the other hand, decimal floating point would fail with 1/3 + 1/3 != 2/3.The general rule is that, in base b, you have finite positional ("decimal") representations of numbers p/q where q is a divisor of bˆn for some n. So e.g. 1/10 doesn't have a finite binary representation because 10 = 2 * 5, and that factor 5 ensures 10 is never a divisor of a power of 2. Likewise, 3 is coprime with 10, so you can't represent 1/3 in decimal.
by pdpi