在 Lua 中计算大幂时出现无法解释的行为

Unexplained behaviour when calculating large powers in Lua

在 Lua 中做一些练习时,我偶然发现了一些(对我来说)非常奇怪的行为,我无法解释。下面的代码应该计算 2 <= a, b <= 100 的 a^b 形式的不同项的数量。This 代码提供了正确的答案,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)

然而,这段代码产生了不同的答案(只有else分支中的'print()'被注释掉了):

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 作为答案。注释掉的那一行没有进行任何计算,只是输出到屏幕上。然而,它似乎影响了计算的结果。我是否发现了一个支持量子力学定律的宏观系统? ;)

不,但是说真的,我在这里遗漏了一些东西,如果有更多经验和知识的人能为我指明正确的方向,我将不胜感激。

提前致谢!

Lua数一般是floating point numbers. On most machines, that means practically double in C99 parlance which are represented by IEEE 754浮点数。

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

特别是,Lua table 正在计算一些哈希值并测试是否相等,浮点数上的相等性 不是 数学实数上的相等性.因此,使用浮点数作为 tables 的键是有风险的。

像 9898 这样的大数字在 IEEE 754 中不是完全...

从道德上讲,如果您使用数字作为某些 Lua table 的键,您最好让该数字是一些 整数 来准确表示table在IEEE754中,所以具体是一个小于252

的整数

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

顺便说一句,在我的 Linux/Debian/Sid/x86-64 桌面上,Debian 打包 Lua 5.2.4-1 和 Debian 打包 Lua 5.3.1-1,两个程序都给出 9183。