在我的引擎中,我有一个用于编写脚本的Lua VM。在脚本中,我写了类似的东西:
stage = stage + 1
if (stage == 5) then ... end
和
objnum = tonumber("5")
if (stage == objnum)
根据Lua的消息来源,Lua在比较它所使用的内部数字类型的双精度时使用了一个简单的等式运算符。
我在处理浮点值时意识到精度问题,所以我想知道比较是否安全,也就是说,使用Lua的默认'=='操作简单地比较这些数字会有问题吗?如果是这样,是否有任何对策我可以确保1 + 2总是比较等于3?将值转换为字符串是否有效?
答案 0 :(得分:8)
通过转换为字符串然后比较结果,如果您只关心某些情况下的相等性,那么可以更好。例如:
> print(21, 0.07*300, 21 == 0.07*300, tostring(21) == tostring(0.07*300))
21 21 false true
当我给学生们分配这些数字(0.07和300)并且要求他们实施单位测试时,我学到了这种方法,然后惨遭失败抱怨21不等于21(这是比较实际数字,但是显示字符串值)。这是我们讨论比较浮点值的一个很好的理由。
答案 1 :(得分:2)
我可以使用以确保1 + 2总是比较等于3?
You needn't worry. Lua中的数字类型为double
,它可以比long int
更准确地保存更多整数。
答案 2 :(得分:1)
在某些情况下,对双打的比较和基本操作是安全的。特别是如果数字及其结果可以准确表达 - 包括所有低值整数。
所以2+1 == 3
对双打来说没问题。
注意:我相信对于某些数学函数(例如pow
和sqrt
)甚至有一些保证,如果您的编译器/库尊重那些,那么sqrt(4.0)==2.0
或4.0 == pow(2.0,2.0)
将可靠的是真的。
答案 3 :(得分:1)
默认情况下,Lua是用c ++浮点数编译的,在幕后数字比较可归结为c / c ++中的浮点数比较,这确实存在问题并在几个线程中进行了讨论,例如: most-effective-way-for-float-and-double-comparison
通过将所有数字(包括c ++整数)转换为浮点数,Lua使情况稍微恶化。所以你需要牢记这一点。