第一天 Lua - 因 for 循环而感到困惑

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

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

点赞
用户836646
用户836646

通常,在任何语言中使用浮点数 / 双浮点数时,如果出现一些奇怪的情况,请搜索关于特定语言中浮点数 / 双浮点数的存储方式的信息。

这个问题已经在这里得到了回答。

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

2013-09-27 06:51:53
用户2195474
用户2195474

在 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-27 06:52:24
用户1009479
用户1009479
```lua
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-27 06:54:55
用户485561
用户485561

Lua通常使用ieee754 binary64格式来表示数字(“通常”是因为实际上取决于基础的C实现)。在binary64中,最接近0.2的数字为0x3FC999999999999A,或近似等于0.200000000000000011102230246252

在进行计算之前,代码中的0.2被舍入为这个数字。

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

2013-09-27 06:58:05