Perl尾数与其他双打不同

Kon*_*ele 5 double perl numeric mantissa

我正试图在浮动中扫描:13.8518009935297.第一个例程是我自己的,第二个是MacOSX libc的strtod,第三个是GMP的mpf_get_d(),第四个是perls numeric.c:Perl_my_atof2().

我用这个片段打印尾数:

union ieee_double {
        struct {
                uint32_t    fracl;
                uint32_t    frach:20;
                uint32_t    exp:11;
                uint32_t    sign:1;
        } s;
        double d;
        uint64_t l;
};

 union ieee_double l0;
 l0.d = .... 
 printf("... 0x%x 0x%x\n", l0.s.frach, l0.s.fracl);
Run Code Online (Sandbox Code Playgroud)

这四个函数的返回值是:

my-func : 0xbb41f 0x4283d21b 
 strtod : 0xbb41f 0x4283d21c  
GMP     : 0xbb41f 0x4283d21b
perl    : 0xbb41f 0x4283d232
Run Code Online (Sandbox Code Playgroud)

前三个函数之间的差异是四舍五入.但是perl的尾数完全不同步.

如果我再次将所有四个双打打印到一个字符串,我得到相同的十进制双回,数字似乎相等.

我的问题:my-func,strtod,GMP之间的区别在于四舍五入.但是,为什么perl的尾数太多不同步,但如果转换回十进制,它最终会再次变为相同的数字.差异是22,所以应该用小数表示.我怎么解释这个?

追加: 对不起,我想我发现了问题:

  $r = rand(25);
  $t = $p->tokenize_str("$r");
Run Code Online (Sandbox Code Playgroud)

tokenize_str()是我从string到double的转换实现.但是perl stringify"$ r"打印出$ r为13.8518009935297,这已经是截断了.$ r的实际值是不同的,所以当我最后使用$ r的$ t的二进制文件时,我会得到不同的值.

BOC*_*BOC 0

这是一些perl代码来回答你的问题:

perl -le '($frac1, $frach)=unpack("II", pack "d", .0+"13.8518009935297");
print sprintf("%d %d 0x%03x 0x%04x", ($frach >> 31)&1, ($frach>>20)&0x5ff, $frach & 0xfffff, $frac1)'
Run Code Online (Sandbox Code Playgroud)

-> 0 1026 0xbb41f 0x4283d21c

Perl 给出与 strtod 相同的结果。区别在于您在附录中指出的错误。