整数域

lua-users home
wiki

以下代码计算了 Lua(双精度浮点数)可以精确表示的整数的实际范围 - 此外,它还是“连续逼近”技术的一个很好的例子。

--**** should be compatible with 5.xx
function intlimit()
  local floor = math.floor

  -- get highest power of 2 which Lua can still handle as integer
  local step = 2
  while true do
    local nextstep = step*2
    if nextstep-(nextstep-1) == 1 and nextstep > 0 then
      step = nextstep
    else
      break
    end
  end

  -- now get the highest number which Lua can still handle as integer
  local limit,step = step,floor(step/2)
  while step > 0 do
    local nextlimit = limit+step
    if nextlimit-(nextlimit-1) == 1 and nextlimit > 0 then
      limit = nextlimit
    end
    step = floor(step/2)
  end
  return limit
end

Example

  local limit = intlimit()

  print()
  print("IntegerDomain - what is the largest supported integer number?")
  print()

--**** do not rely on Lua to print "limit" properly by itself!
--local printablelimit = string.format("%d", limit)         -- fails under Lua!
  local printablelimit = string.format("%.16e", limit)

  print("supported integer range is: -" ..
        printablelimit .. "...+" .. printablelimit)

正如你所见,Lua 在处理大整数时没有问题 - 只要你不尝试将它们转换为字符串 ;-)

为了确保整数能正确地转换为字符串(而不是科学计数法),请使用 format.string("%.0f",x) 而不是 tostring(x)。

--AndreasRozek


能否证明其正确性?它是否假定 IEEE?--DavidManura

嗯,让我想想这些要求。

此外,我还做了另外两个假设:

这两个假设都可以轻松地显式检查(不要忘记在测试负数时将“floor”替换为“ceil”!)。

如果满足这些要求,就可以使用“连续逼近”来获得最大的可表示整数。

由于我没有提及任何具体结果,所以我并没有真正假定 IEEE,除了我上面显示的假设(符号位编码保证了对称性)以及我选择的测试。

--AndreasRozek

---- 我在 lua 5.1 上运行了这个算法,但它不太奏效:它给出的最大整数是 9007199254740994,但 print(string.format("%0.f", intlimit()-1) 返回 9007199254740992 而不是 9007199254740993。我修正了代码中的三处。

--4xel


RecentChanges · preferences
编辑 · 历史
最后编辑于 2016 年 4 月 15 日 下午 12:54 GMT (diff)