第一天lua - 被for循环弄糊涂了

时间:2013-09-27 06:40:01

标签: variables for-loop lua int

非常简单的问题,但我真的很困惑: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

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

4 个答案:

答案 0 :(得分:4)

Lua通常用ieee754 binary64格式表示数字("通常"因为表示实际上取决于底层的C实现)。 binary64中的closest number0.20x3FC999999999999A,或大约为0.200000000000000011102230246252

在进行计算之前,源代码中的0.2将四舍五入为此数字。

由于0.200000000000000011102230246252大于2,因此在最后一步中数字会大于5,因此循环结束时大约为4.8

答案 1 :(得分: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为数字引入了一个新的整数子类型。见Changes in the Language

答案 2 :(得分:1)

像往常一样,当使用任何语言的浮点数/双打时,你会发现一些奇怪的事情,搜索浮点数/双打如何以特定语言存储。

已经回答here

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

答案 3 :(得分: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 fails to evaluate math.abs(29.7 - 30) <= 0.3