Perl中的最大整数

时间:2014-08-01 13:59:45

标签: perl integer max limit

设置$i=0并在++$i增加时执行1。我们会达到哪个号码?

请注意,它可能与Perl中的最大整数(在标题中提到的)不同,因为相邻整数之间可能存在大于{{1}}的间隙。

3 个答案:

答案 0 :(得分:15)

“整数”可以指一系列数据类型(int16_tuint32_t等)。这些数字可以代表没有差距。

“整数”也可以指不带小数分量的数字,无论用于存储它的变量的类型如何。 ++将在数据类型之间无缝转换,因此这与此问题相关。

浮点数可以在这个意义上存储整数,并且可以将非常大的数字存储为浮点数,而无法向它们添加一个。原因是使用以下格式存储浮点指针号:

[+/-]1._____..._____ * 2**____

例如,假设您的浮点数的尾数可以存储小数点后的52位,并且您想将1添加到2**53

     __52 bits__
    /           \
  1.00000...00000  * 2**53    Large power of two
+ 1.00000...00000  * 2**0     1
--------------------------
  1.00000...00000  * 2**53
+ 0.00000...000001 * 2**53    Normalized exponents
--------------------------
  1.00000...00000  * 2**53
+ 0.00000...00000  * 2**53    What we really get due to limited number of bits
--------------------------
  1.00000...00000  * 2**53    Original large power of two

因此在使用浮点数时可能会出现间隙。但是,您从一个存储为有符号整数的数字开始。

$ perl -MB=svref_2object,SVf_IVisUV,SVf_NOK -e'
   $i = 0;
   $sv = svref_2object(\$i);
   print $sv->FLAGS & SVf_NOK    ? "NV\n"   # Float
      :  $sv->FLAGS & SVf_IVisUV ? "UV\n"   # Unsigned int
      :                            "IV\n";  # Signed int
'
IV

++$i会将数字保留为有符号整数值(“IV”),直到它不再存在。此时,它将开始使用无符号整数值(“UV”)。

$ perl -MConfig -MB=svref_2object,SVf_IVisUV,SVf_NOK -e'
   $i = hex("7F".("FF"x($Config{ivsize}-2))."FD");
   $sv = svref_2object(\$i);
   for (1..4) {
      ++$i;
      printf $sv->FLAGS & SVf_NOK    ? "NV %.0f\n"
         :   $sv->FLAGS & SVf_IVisUV ? "UV %u\n"
         :                             "IV %d\n", $i;
   }
'
IV 2147483646
IV 2147483647            <-- 2**31 - 1  Largest IV
UV 2147483648
UV 2147483649

IV 9223372036854775806
IV 9223372036854775807   <-- 2**63 - 1  Largest IV
UV 9223372036854775808
UV 9223372036854775809

仍然没有差距因为还没有使用浮点数。但Perl最终将使用浮点数(“NV”),因为它们的范围远大于整数。当++$i用完无符号整数时,它将切换到使用浮点数。

发生这种情况取决于你的Perl构建。并非所有Perl版本都具有相同的整数和浮点数。

在一台机器上:

$ perl -V:[in]vsize
ivsize='4';   # 32-bit integers
nvsize='8';   # 64-bit floats

另一个:

$ perl -V:[in]vsize
ivsize='8';   # 64-bit integers
nvsize='8';   # 64-bit floats

在nvsize大于ivsize

的系统上

在这些系统上,第一个间隙将发生在最大无符号整数之上。如果您的系统使用IEEE双精度浮点数,则浮点数具有53位精度。它们可以毫无损失地表示从-2 53 到2 53 (包括)的所有整数。 ++将无法超越该值。

$ perl -MConfig -MB=svref_2object,SVf_IVisUV,SVf_NOK -e'
   $i = eval($Config{nv_overflows_integers_at}) - 3;
   $sv = svref_2object(\$i);
   for (1..4) {
      ++$i;
      printf $sv->FLAGS & SVf_NOK    ? "NV %.0f\n"
         :   $sv->FLAGS & SVf_IVisUV ? "UV %u\n"
         :                             "IV %d\n", $i;
   }
'
NV 9007199254740990
NV 9007199254740991
NV 9007199254740992   <-- 2**53      Requires 1 bit of precision as a float
NV 9007199254740992   <-- 2**53 + 1  Requires 54 bits of precision as a float
                                        but only 53 are available.

在nvsize不大于ivsize

的系统上

在这些系统上,第一个间隙将在最大无符号整数之前发生。切换到浮动指针编号可以让你更进一步(2的大功率),但就是这样。 ++将无法超出最大无符号整数+ 1。

$ perl -MConfig -MB=svref_2object,SVf_IVisUV,SVf_NOK -e'
   $i = hex(("FF"x($Config{ivsize}-1))."FD");
   $sv = svref_2object(\$i);
   for (1..4) {
      ++$i;
      printf $sv->FLAGS & SVf_NOK    ? "NV %.0f\n"
         :   $sv->FLAGS & SVf_IVisUV ? "UV %u\n"
         :                             "IV %d\n", $i;
   }
'
UV 18446744073709551614
UV 18446744073709551615   <-- 2**64 - 1  Largest UV
NV 18446744073709551616   <-- 2**64      Requires 1 bit of precision as a float
NV 18446744073709551616   <-- 2**64 + 1  Requires 65 bits of precision as a float
                                            but only 53 are available.

答案 1 :(得分:2)

这是32位perl,

perl -e "$x=2**53-5; printf qq{%.f\n}, ++$x for 1..10"
9007199254740988
9007199254740989
9007199254740990
9007199254740991
9007199254740992
9007199254740992
9007199254740992
9007199254740992
9007199254740992
9007199254740992

答案 2 :(得分:0)

好吧,在我的64位计算机上18446744073709551615~0更容易),之后它再次增加到1.84467440737096e+19并停止递增。< / p>