Lua无法评估math.abs(29.7-30)< = 0.3 [英] Lua fails to evaluate math.abs(29.7 - 30) <= 0.3

查看:180
本文介绍了Lua无法评估math.abs(29.7-30)< = 0.3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天早晨,我在Lua脚本上发现了一个错误,但看起来很奇怪.这种评估怎么会以这种方式失败?可以在此处

Today morning I found a bug on my Lua Script, wich seem very weird. How can this evaluation fail this way? Examples can be tested in here

第一个示例:

if( math.abs(29.7 - 30) <=  0.3 ) then
  result = 1
else
  result = 0
end
print("result = "..result )
-->> result = 0

第二个例子:

if( 0.3 <=  0.3 ) then
   result = 1
else
   result = 0
end
  print("result = "..result )
-->> result = 1

第三个例子

if( math.abs(29.7-30) == 0.3 )then
   print("Lua says: "..math.abs(29.7-30).." == 0.3")
else
   print("Lua says: "..math.abs(29.7-30).." ~= 0.3")
end
-->> Lua says: 0.3 ~= 0.3 WHAT?

我真的很困惑,我想理解这一点,以避免将来出现类似的错误.谢谢

I am really confuse, and I would like to understand this to avoid similiar bugs in the future. Thanks

推荐答案

Lua使用(IEEE 754)64位双精度浮点数这一事实使您深受打击.

You are being hit by the fact that Lua uses (IEEE 754) 64-bit double-precision floating point numbers.

看下面的例子
> print(0.3 == 0.3)
true
> print(0.3 <= 0.3)
true
> print(0.3 >= 0.3)
true

Look at the following examples
> 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

The actual value of 0.3 in memory is:
> 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

Now look at you example:
> 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

The actual value of 29.7-30 is:
> 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

The actual value of math.abs(29.7-30) is:
> 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

And just for fun the value of math.abs(-0.3) is:
> print(string.format("%1.64f", math.abs(-0.3)))
0.2999999999999999888977697537484345957636833190917968750000000000

有两种解决方法可以解决您的问题,第一种方法是阅读每个计算机科学家都应该了解浮点运算,并理解它:-).第二种解决方案是将Lua配置为对数字使用其他类型,请参见值和类型获取提示.

There are two solutions to you problem, the first is read What Every Computer Scientist Should Know About Floating-Point Arithmetic, and understand it :-). The second solution is to configure Lua to use another type for numbers, see Values and Types for hints.

修改 我只是想到了另一种解决"问题的方法,但这有点麻烦,并且不能保证始终有效.您可以在lua中使用定点数字,方法是先将浮点数转换为具有固定精度的字符串.

Edit I just thought of another way of "solving" the problem, but it is a bit of a hack, and not guarantied to always work. You can use fixed point numbers in lua by first converting the float to a string with a fixed precision.

在您的情况下,该外观类似于:

In your case that would look something like:

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))

但是,您必须确保对所有比较使用的精度都足够高且相同.

However you must make sure that you use a precision that is both adequate and the same for all you comparisons.

这篇关于Lua无法评估math.abs(29.7-30)&lt; = 0.3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆