Lua中数字的最大值是多少?

30

文档中似乎没有明确的答案。

我对增加一个变量time感兴趣,它计算自程序启动以来经过的秒数。如果最大值可以远超未来,例如100年,那么我不在乎让变量无限增加。否则,我需要考虑一个好的时间点将time重置为0。

6个回答

42

默认情况下,数字是double类型,在大多数编译器中都是IEEE 64位浮点数。这意味着10位指数,因此最大数大约为2的1024次方,或5.6e300年。时间很长。

现在,如果您正在递增它,可能更感兴趣的是整数范围。52位的尾数意味着可以使用整数精度的最高数字是2的52次方,约为4.5e15。在每年31,557,600秒的情况下,这是1.427e8,几乎为1.5亿年。对于任何进程来说,仍然是非常长的运行时间。

更新2014-12-30:Lua 5.3(即将发布)通过编译标志添加了对32位或64位整数值的支持。


41
谢谢,我可以忍受在150亿年后被一些程序员所憎恨。 - Kai
4
顺便提一下,虽然它有一个52位的尾数,但还有一个“额外”的隐含精度位,所以你最多只能增加约2^53。 - Eloff
2
2^53是第一个不会增加的数字。这是因为IEEE-754标准下,尾数有一个“隐藏”的最高位,如果指数不为零且不是最大指数,则默认为1。当值为2^53时,仅该隐藏位被设置,最低有效位未存储,但其值为零,因此该值仍然是完全正确的。增加该值将增加未存储的位,因此不会影响结果。请注意,可以存储较高的值,但只会存储它们的高53位,低位将被清零。 - doug65536

12

虽然tydok提到的PiL 2.3是正确而且适当的参考,而Javier的回答在实践中也是正确的,但我认为Lua中数字的讨论应该包含其他细节。

Lua解释器被设计为嵌入在应用程序中,通常作为配置和/或脚本语言。构建应用程序时,通常会配置一些功能以适应应用程序的需求。

可用于数字的精确数值类型可供配置。当编译不支持硬件浮点运算的平台时(特别是在嵌入式系统或机顶盒游戏控制台应用程序中),加载第三方模块不重要时,选择整数类型作为默认类型而非double是合理的。偶尔,切换到float也是合理的。

但是,有些应用程序需要64位整数,或者大多数数字可以是整数,但偶尔需要浮点算术运算。对于这些情况,可以使用LNUM补丁来改变Lua核心。

LNUM更改了核心,使数字存储为整数或浮点数,并允许为每个精度选择进行多个可配置选项。

因此,关于Lua数字的最大值的最终答案取决于编译时所选择的解释器配置,以及您是否担心可表示的最大大小或最大整数。即使在这种情况下,也已经做出了一些工作,使大整数与浮点表示相协调。


3
LNUM 很棒,无论是在非 FPU 处理器(如一些 ARM 处理器)上的速度,还是在那些需要真正使用 64 位整数运算的罕见场合中。 - Javier

4
这是其他答案中提到的最大值。这就是1.8e308的来源:
HighestNumber = 0
for i = 971, 1024 do
    HighestNumber = HighestNumber + (2 ^ i)
    print(HighestNumber)
end

LuaJIT result


1

我在lua用户网站上找到了这个邮件

Lua核心不使用64位数据类型,除非通过size_tptrdiff_t(在64位系统上为64位)隐式使用。

sizeof( float ) == 4
sizeof( double) == 8

你可以将lua_Number定义为double(默认),float或至少有32位的任何整数。但是会有一些副作用,并且由于浮点数或整数的有限范围,某些扩展可能无法正常工作。不过,核心应该没问题。


1
使用Lua5.1或Lua5.2
最大格式化数字:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

如果您将结尾的68更改为69,它仍然只显示68。大于上面数字的数字会返回math.huge(即inf)。
这相当于:1.8x10 ^ 308或略低于2 ^ 1024。
自己试试吧:
print(string.format("%.0f",number))

0

我偶然发现了这个问题,因为我自己也遇到了一个非常类似的问题。我目前正在使用LÖVE2D进行编程,它使用基于Lua 5.1LuaJIT,因此没有整数。我的个人问题是:我能否使用单个变量来跟踪时间?

对于时间,更重要的不是知道最高值是多少,而是首先问自己需要什么精度级别,比如毫秒、厘米或十分之一秒(1、10或100毫秒)。甚至是秒。为什么呢?

你看,即使你可以在Lua 5.1数字限制下理论上将数千年相加得到秒数,这些数字限制约为2^1024,但问题是,在经过一段非常长的时间后(但这完全取决于你的边界,如果你正在处理天文应用程序会怎样?),你对时刻的区分能力会急剧降低...

> t = 2^1023
> print(t)
8.9884656743116e+307
> print(t+1) -- let's assume your dt is of 1 second
8.9884656743116e+307

在某些时候,甚至秒的差异也变得毫无意义。因此,我的建议是直接检查您所需精度的限制...

> a,b = 0,0.1 -- the precision is 100 ms
> while a~=b do a,b = b,b+1 end
interrupted!

我甚至没有等到达到极限,我就打断了循环,同时仍然将0.1添加到上一个时刻改变基础值a。

> print(a/60/60/24/365) -- check current limit in years!
251.54387084919

因此,在使用Lua 5.1和LuaJIT时,使用单个变量跟踪时间绝对是安全的。就我个人而言,由于我正在编写一个通用框架,我更喜欢将秒数从更小的分数中分离出来,以保证最大精度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接