我有以下测试用例:
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
最后一行应为1000000000000000001
,因为这是bar
的值,但由于某种原因,它不是。1000000000000000000
。这不仅适用于tacocat
,我还没有找到另一个给出正确值的数字。任何人都可以解释为什么会发生这种情况吗?
答案 0 :(得分:5)
您将数字格式化为浮点数,而不是整数。那是%.0f
正在做的事情。在某些时候,浮标会失去精确度。例如,double
在大约16个十进制数字后将失去精度。
如果要将整数格式化为整数,则需要使用standard printf
rules将其格式化为整数:
string.format("%i", bar)
答案 1 :(得分:3)
log2(1000000000000000000)
介于59和60之间,这意味着该数字的二进制表示需要60位。 double
- 精度浮点数只有53位精度,加上2位幂指数和11位范围。因此,要将大数字存储为浮点(这是您使用%f
格式说明符所请求的),从数字的末尾开始将6到7位的精度切除,并将整数乘以在这种情况下,我认为2的幂可以让它回到范围内(2 59 )。删除这些最终位会消除允许1000000000000000000
和1000000000000000001
彼此不同的精度。
(这不是浮点的特别精确的描述,如果我的数字或描述不准确,请道歉。)