3

非常简单的问题,但我真的很困惑:P

> for x = 0, 5, 0.2 do
print (x)
end

这个循环只计算到 4.8(0.2 再多一步将得到 5,不是吗?)

但以下 for 循环计数为 5

> for x = 0, 5, 1 do
print (x)
end

有人可以解释或参考手册,这些输出背后的原因。也许我应该将变量定义为浮点数?

4

4 回答 4

4

Lua 通常以ieee754 binary64格式表示数字(“通常”是因为表示实际上取决于底层 C 实现)。binary64 中最接近的数字或近似。0.20x3FC999999999999A0.200000000000000011102230246252

在进行计算0.2之前,源代码中的 会四舍五入到这个数字。

由于0.200000000000000011102230246252大于2,因此数字变得大于5最后一步,因此循环在大约 处结束4.8

于 2013-09-27T06:58:05.663 回答
3
for x = 0, 5, 0.2 do print (x) end

这个数字for循环会将步长添加0.2到初始值0,执行处理 ( print(x)) 直到值为<=5. 问题是,对于浮点数,0.2不能精确表示,所以有一点舍入。所以当你认为它应该总和为5时,它可能会大一点。

对于不是很大的整数,可以用双精度浮点数精确表示,所以没问题。


对于你学习 Lua 的第一天,一个小提示:

  • 使用Lua作为语言名称,而不是 LUA 或 lua。
  • Lua 只有一种数字类型,double默认情况下。* 见下文

*: 这不再是真的。Lua 5.3 为数字引入了一个新的整数子类型。查看语言的变化

于 2013-09-27T06:54:55.727 回答
1

像往常一样,在使用任何语言的浮点数/双精度数时,您会遇到一些奇怪的事情,请搜索浮点数/双精度数如何以特定语言存储。

这已经在这里回答了

正如@jbr已经指出的那样, 0.2 存储为0.2000000000000000111022302462515654042363166809082031250000000000,当 for 循环运行时,它会检查该值是否小于或等于 5,并且由于这些双精度数的总和略大于 5,因此它不会将其解释为此循环的成员并立即退出。

于 2013-09-27T06:51:53.323 回答
1

你在这里遇到的是很多人在 Lua 中感到困惑的东西。在 Lua 中,所有数字都是双精度数,这意味着并非所有数字都有精确的表示,0.2是这些数字之一:

> print(string.format("%1.64f",math.abs(0.2)))
0.2000000000000000111022302462515654042363166809082031250000000000

所以你在这里得到的是一个累积的错误。

如果您尝试0.25

> print(string.format("%1.64f",math.abs(0.25)))
0.2500000000000000000000000000000000000000000000000000000000000000

所以

for x = 0, 5, 0.25 do
  print(x)
end

按预期工作,有关更多信息,请参阅Lua 无法评估 math.abs(29.7 - 30) <= 0.3

于 2013-09-27T06:52:24.137 回答