我正试图在浮动中扫描: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);
这四个函数的返回值是:
my-func : 0xbb41f 0x4283d21b
strtod : 0xbb41f 0x4283d21c
GMP : 0xbb41f 0x4283d21b
perl : 0xbb41f 0x4283d232
前三个函数之间的差异是四舍五入。 但是perl的尾数完全不同步。
如果我再次将所有四个双打打印成一个字符串,我就得到了 相同的十进制后退,数字似乎相等。
我的问题: my-func,strtod,GMP之间的区别在于四舍五入。然而, 为什么perl的尾数如此不同步,但仍然如此 转换回十进制,它再次以相同的数字结束。 差异是22,所以应该用小数表示 分数。我怎么解释这个?
附加: 对不起,我想我发现了问题:
$r = rand(25);
$t = $p->tokenize_str("$r");
tokenize_str()是我从string到double的转换实现。 然而,perl stringify“$ r”打印出$ r为13.8518009935297,这是一个 已截断。 $ r的实际值是不同的,所以当我在最后的二进制文件 $ t与$ r我得到的分歧值。
答案 0 :(得分: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)'
- > 0 1026 0xbb41f 0x4283d21c
Perl给出与strtod相同的结果。不同之处在于您在附加中指出的错误。