你受到了Lua使用(IEEE 754)64位双精度浮点数的事实。
请看下面的例子
> print(0.3 == 0.3)
true
> print(0.3 <= 0.3)
true
> print(0.3 >= 0.3)
true
的0.3
在存储器中的实际值是:
> print(string.format("%1.64f",math.abs(-0.3)))
0.2999999999999999888977697537484345957636833190917968750000000000
现在看看你例子:
> print(math.abs(29.7-30) == 0.3)
false
> print(math.abs(29.7-30) >= 0.3)
true
> print(math.abs(29.7-30) <= 0.3)
false
的29.7-30
的实际值是:
> print(string.format("%1.64f",29.7-30))
-0.3000000000000007105427357601001858711242675781250000000000000000
的math.abs(29.7-30)
的实际值是:
> print(string.format("%1.64f", math.abs(29.7-30))
0.3000000000000007105427357601001858711242675781250000000000000000
而只是为了好玩的math.abs(-0.3)
值:
> print(string.format("%1.64f", math.abs(-0.3)))
0.2999999999999999888977697537484345957636833190917968750000000000
有两种解决方案你亲第一个是What Every Computer Scientist Should Know About Floating-Point Arithmetic,理解它:-)。第二个解决方案是将Lua配置为使用其他类型的数字,请参阅Values and Types提示。
编辑 我只是想到了另一种“解决”问题的方式,但它有点破解,而且不保证总能正常工作。您可以在lua中使用固定点数字,首先将float转换为具有固定精度的字符串。
在你的情况,将是这个样子:
a = string.format("%1.1f", math.abs(29.7 - 30))
print(a == "0.3")
或略偏稳健:
a = string.format("%1.1f", math.abs(29.7 - 30))
print(a == string.format("%1.1f", 0.3))
但是你必须确保你使用的精度,既充分和相同所有你比较。
来源
2013-05-02 08:11:05
jbr
哦,我的上帝。我从来没有这样做过。非常好的理由。我真的很惊讶。任何建议使这项工作?喜欢这个? 对比0.31? – MRodrigues 2013-05-02 08:26:31
我的最佳建议是在我编辑的编辑中,除了理解它之外,没有简单的解决方法。 – jbr 2013-05-02 08:32:05
请注意,这是一个问题是测试精确相等的情况。虽然有些情况下您可以从浮点计算得到准确的结果,但这不是其中的一种情况。使用任意精度表示的替代方案在计算上非常昂贵,因此需要妥协。引用的文章深入解释。 – RBerteig 2013-05-02 09:04:12