在Lua中计算大功率时出现不明原因的行为

时间:2015-11-12 09:28:49

标签: lua exponential

在Lua做了一些练习,我偶然发现了一些(对我来说)真正奇怪的行为,我无法解释。以下代码应该计算形式的不同术语的数量a ^ b为2< = a,b< = 100. 代码提供正确的答案,9183:

local terms = {}
local cnt = 0
for a = 2, 100 do
  for b = 2, 100 do
    term = math.pow(a, b)
    if not terms[term] then
      terms[term] = string.format("%d exp %d", a, b)
      cnt = cnt + 1
    else
      print(term .. " already in set! (" .. terms[term] .. ")")
    end
  end
end

print(cnt)

但是,代码产生了不同的答案(只有' print()'在else分支中被注释掉了):

local terms = {}
local cnt = 0
for a = 2, 100 do
  for b = 2, 100 do
    term = math.pow(a, b)
    if not terms[term] then
      terms[term] = string.format("%d exp %d", a, b)
      cnt = cnt + 1
    else
      --print(term .. " already in set! (" .. terms[term] .. ")")
    end
  end
end

print(cnt)

有。这让我得到9254作为答案。在该注释掉的行中没有进行计算,只是输出到屏幕。然而,它似乎影响了计算的结果。我是否发现了一个构成量子力学定律的宏观系统? ;)

不,但是说真的,我在这里遗漏了一些东西,如果有经验和知识的人能指出我正确的方向,我会非常感激。

提前致谢!

1 个答案:

答案 0 :(得分:1)

Lua数字通常是floating point个数字。在大多数机器上,这意味着在C99用语中实际上double,由IEEE 754浮点数表示。

你需要阅读http://floating-point-gui.de/(浮点数很令人头疼)。

特别是,Lua表计算一些散列并测试相等性,并且浮点上的相等性在数学实数上相等。因此,使用浮点数作为表的关键是有风险的。

像IEEE 98 这样的大数字

从道德上讲,如果你使用一个数字作为某个Lua表的关键字,你最好将这个数字设置为在IEEE754中可以准确表示的整数,所以具体地说是一个小于2的整数 52

我猜你已被一些特定于实现的工件所困扰。您可以调试Lua C代码(即逐步进入Lua C实现)以查找更多内容。也许一些垃圾收集,或简单的哈希表重组,发生在第一个程序中,但不是在第二个程序中,或不同的舍入规则......

BTW,在我的Linux / Debian / Sid / x86-64桌面上,使用Debian打包的Lua 5.2.4-1和Debian打包的Lua 5.3.1-1,两个程序都给出9183。