Perl 尾数与其他 double 不同

标签 perl double 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);

这四个函数的返回值是:
my-func : 0xbb41f 0x4283d21b 
 strtod : 0xbb41f 0x4283d21c  
GMP     : 0xbb41f 0x4283d21b
perl    : 0xbb41f 0x4283d232

前三个函数之间的区别是四舍五入。
然而,perl 的尾数非常不同步。

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

我的问题:
my-func、strtod、GMP 之间的区别是四舍五入。然而,
为什么 perl 的尾数如此不同步,但是,如果
转换回十进制,它最终再次成为相同的数字。
差是22,所以应该用小数记
分数。我该如何解释?

附加:
对不起,我想我找到了问题所在:
  $r = rand(25);
  $t = $p->tokenize_str("$r");

tokenize_str() 是我实现从字符串到 double 的转换。
然而,perl stringify "$r"将 $r 打印为 13.8518009935297,这是一个
已经截断。
$r 的实际值是不同的,所以当我最后的二进制文件
$t 和 $r 我得到不同的值。

最佳答案

下面是一些 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 相同的结果。不同之处在于您在附录中指出的错误。

关于Perl 尾数与其他 double 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17954479/

相关文章:

perl - 使用 WWW::Mechanize 保存 PDF 文件会损坏它们

perl - my 和 our 之间的区别? (在同一个文件中声明)

c - 内存对齐处理器是否依赖、数据依赖或高速缓存行长度依赖?

允许我为参数分配边界的 Python 曲线拟合库

用于 Gauss-Seidel 迭代求解器的 Python 库?

bash - 将 perl while 循环更改为 shell

Perl 转换为 int 错误但仅限于特定数字

java - 旋转 - 缺乏精度 - Java

java - 比较java中格式的 double 值?

具有椭圆积分和贝塞尔函数的 Java/Scala 数学库?