Perl中的最大整数

Perl中的最大整数,perl,integer,max,limit,Perl,Integer,Max,Limit,设置$i=0并在其增大时执行+$i。我们能打到哪个号码 请注意,它可能与Perl中的最大整数不同(如标题中所述),因为相邻整数之间可能存在大于1的间隙,这是在32位Perl上 perl -e "$x=2**53-5; printf qq{%.f\n}, ++$x for 1..10" 9007199254740988 9007199254740989 9007199254740990 9007199254740991 9007199254740992 9007199254740992 90071

设置
$i=0
并在其增大时执行
+$i
。我们能打到哪个号码


请注意,它可能与Perl中的最大整数不同(如标题中所述),因为相邻整数之间可能存在大于
1

的间隙,这是在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

嗯,在我的64位机器上,它是
18446744073709551615
(比
~0
容易得多),之后它再次增加时间到
1.84467440737096e+19
,并停止递增。

整数可以指一系列数据类型(
int16\u t
uint32\u 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 -V:[in]vsize
ivsize='8';   # 64-bit integers
nvsize='8';   # 64-bit floats
在nvsize大于ivsize的系统上 在这些系统上,第一个间隙将出现在最大无符号整数之上。如果系统使用IEEE双精度浮点,则浮点的精度为53位。它们可以毫无损失地表示-253到253(包括-253)之间的所有整数<代码>++将无法增量超过该值

$ 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.

++$i
总是将一个数字增加1或0(如果该数字太大,下一个数字无法表示)是真的吗?@Wooble:因为有些整数表示为浮点,请看您能否确认可以达到
2**53
perl-E'$i=18446744073709550000;虽然($i+1!=$i){say$i++}'
@choroba:18446744073709550000从
0
无法访问,因为从ССцц27
$x=2**53-5
的回答中可以清楚地看出,
$i=0
IV
@user3849273我的印象是OP并不关心内部。
$ 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
$ 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.
$ 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.