【问题标题】:Unexplained behaviour when calculating large powers in Lua在 Lua 中计算大幂时出现无法解释的行为
【发布时间】:2015-11-12 09:28:48
【问题描述】:

在 Lua 中做一些练习时,我偶然发现了一些(对我而言)非常奇怪的行为,我无法解释。以下代码用于计算 2 此代码提供正确答案,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 特定的列表或论坛上询问...
  • 是的,我想你是对的。我会再等一天左右。如果在那之后没有人给出更具体的答案,我会选择你的答案,因为它给我带来了一些洞察力和一个很棒的网站,我可以阅读并随后传播。
  • 什么版本的 Lua?什么C编译器?什么操作系统? Lua 是如何配置和编译的?
  • 在 Mac OS X 中使用 Lua 5.1.5、5.2.4、5.3.1 时,两个程序都为我输出了相同的 cnt 值。
  • @ChristophFloat:我相信 ZeroBrane Studio 默认使用 LuaJIT 作为其 Lua 5.1 解释器。如果是这种情况,对print 函数的调用可能会阻止for 循环的JIT 编译,从而导致意外行为。你可以试试在开头加jit.off()看看是不是这样。

标签: lua exponential


【解决方案1】:

Lua 编号一般为floating point 编号。在大多数机器上,这实际上意味着 C99 用语中的 double,由 IEEE 754 浮点数表示。

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

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

像 9898 这样的大数在 IEEE 754 中完全表示...

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

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

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

【讨论】:

  • 嘿,非常感谢!我已经怀疑这个问题与 FPN 有关,但我仍然不明白为什么第一个代码示例 always 让我得到正确答案,而第二个示例 always 让我得到(相同的)错误答案。 (很棒的网站,顺便说一句。不知道,谢谢!)
  • 选择这个答案。连同问题的 cmets,@BasileStarynkevitch,你让我对正在发生的事情有了一个相当不错的了解。
猜你喜欢
  • 1970-01-01
  • 2015-07-22
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
相关资源
最近更新 更多