我在读《Lua编程》这本书时遇到了这个问题,我不知道如何让计算结果为零。
当我将结果格式化为浮点数时:
io.write(string.format("%f", 12.7 - 20 + 7.3)) -- -0.000000
但是如果我尝试将其转换为整数,我会得到 nil:
io.write(math.tointeger(12.7 - 20 + 7.3) -- nil
有什么解释为什么结果变成这样吗?以及如何实现结果为零?
我尝试将计算分成两个不同的变量。
local x = 12.7 - 20
local y = 7.3
io.write(x + y)
事实证明,在其他浮点计算中不会发生这种情况。
io.write(3.7 - 13 + 9.3) -- 0.0
io.write(14.4 - 31 + 16.6) -- 0.0
-7.3 + 7.3 也不会发生这种情况。结果是0.0。
当我认为问题只是出现在12.7 - 20 + 7.3时,我得到了这个结果:
local x = 14.7 - 20
local y = 5.3
io.write(x + y) -- -8.8817841970013e-016
任何 7.3 及以下的计算都不会返回 0.0:
io.write(12.7 - 20 + 7.3)
io.write(13.7 - 20 + 6.3)
io.write(14.7 - 20 + 5.3)
io.write(15.7 - 20 + 4.3)
但是,当它是8.3时,它返回0.0:
io.write(11.7 - 20 + 8.3) -- 0.0
我相信这是由于浮点运算错误造成的。浮点数旨在表示任何小数点数字。但由于计算机使用二进制位并且每个变量只能使用这么多位,因此它们只能表示一组有限的小数位数。
这种计算事实意味着某些小数点数字在转换为二进制格式时是近似的。来自近似值的任何计算结果都会有一点偏差,因此您会收到意想不到的答案。
这种近似产生的误差通常非常大,在您的情况下约为 e-16。但是,当断言浮点数相等时,您始终需要一个容差来解释错误。