Reputation: 2304
I have the following test case:
Lua 5.3.2 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> foo = 1000000000000000000
> bar = foo + 1
> bar
1000000000000000001
> string.format("%.0f", foo)
1000000000000000000
> string.format("%.0f", bar)
1000000000000000000
That last line should be 1000000000000000001
, since that's the value of bar
, but for some reason it's not. This doesn't only apply to 1000000000000000000
, I've yet to find another number over that one which gives the correct value. Can anyone give an explanation for why this happens?
Upvotes: 3
Views: 402
Reputation: 36517
log2(1000000000000000000)
is between 59 and 60, which means that the binary representation of that number needs 60 bits. double
-precision floating point numbers have only 53 bits of precision, plus a power-of-two exponent with 11 bits of range. So to store that large of a number as floating point (which is what you requested with the %f
format specifier), six to seven bits of precision are chopped off the end of the number, and the whole thing is multiplied by a power of two to get it back in range (259 in this case, I think). Chopping off those final bits removes the precision that allows 1000000000000000000
and 1000000000000000001
to be distinct from each other.
(This is not a particularly precise description of floating point, apologies if my numbers or descriptions are not exact.)
Upvotes: 3
Reputation: 473966
You're formatting the number as floating-point, not integer. That's what %.0f
is doing. At some point, floats lose precision. double
, for example, will lose precision after about 16 decimal digits.
If you want to format an integer as an integer, then you need to format it as an integer, using standard printf
rules:
string.format("%i", bar)
Upvotes: 5