在引擎盖下perl 64位整数

elh*_*efe 3 perl 64-bit integer

我对perl中64位整数的内部表示感到困惑.

Ubuntu 12.04,perl 5.16.0:

print 18440000000000001000 . "\n";
print 18450000000000001000 . "\n";
print -9220000000000001000 . "\n";
print -9230000000000001000 . "\n";
Run Code Online (Sandbox Code Playgroud)

输出:

18440000000000001000
1.845e+19
-9220000000000001000
-9.23e+18
Run Code Online (Sandbox Code Playgroud)

显然正数溢出并被强制浮动,相应的精度损失,在2 ^ 64.但是 - 没有留下符号位的空间,那么负数高达-2 ^ 63的情况如何?

Mar*_*erg 5

Perl数字表示为a IV或a UV.它是SV结构本身的旗帜.

我猜测一个号码签名后会UV变成一个IV,反之亦然.

具体来说,查看SV定义:

#define _SV_HEAD_UNION \
union {                             \
    char*   svu_pv;         /* pointer to malloced string */        \
    IV      svu_iv;                 \
    UV      svu_uv;                 \
    SV*     svu_rv;         /* pointer to another SV */             \
    SV**    svu_array;              \
    HE**    svu_hash;               \
    GP*     svu_gp;                 \
    PerlIO *svu_fp;                 \
}   sv_u
Run Code Online (Sandbox Code Playgroud)

SvIOKSvUOK标志可以用来看看的实际有效的领域SV是.

  • 对于不熟悉perl内部的人稍微翻译:64位perl上的数字标量可以是带符号*或*无符号的64位int,而perl将在它们之间进行转换,几乎所有的都是正确的选择时间.这意味着您可以轻松处理-2 ^ 63和+ 2 ^ 64之间的数字,并且超出此范围的结果是"仅",您将降级为浮点数. (7认同)
  • "64位perl"包括64位系统上的大多数perls,以及使用`ivsize = 8`的32位系统上的perls,但不包括`ivsize = 4`的perls.在那些perls上,`IV是32位符号,'UV`是无符号32位,但双精度浮点提供的整数精度为+/- 2 ^ 53,用于`NV`. (2认同)