我正在尝试以浮点数进行扫描: 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() 是我实现从字符串到双精度的转换。但是 perl stringify "$r" 将 $r 打印为 13.8518009935297,这已经是截断了。$r 的实际值是不同的,所以当我最后将 $t 和 $r 的二进制文件放在一起时,我得到的值是不同的。