代码之家  ›  专栏  ›  技术社区  ›  queen3

FPU命令FLDL在ST0中将双精度转换为长双精度

  •  2
  • queen3  · 技术社区  · 13 年前

    我的C++代码中有一个双重值:

    double inch = 25.399999618530273;
    

    当用于计算时,使用将其加载到FPU st0寄存器

    fldl -0x90(%ebp)
    

    我可以看到,0x90(%ebp)处的双精度是正确的值。然而,在FLDL之后,它在st0寄存器中显示为长的双精度值25.3999996185302734375,即使我使用-mpc64-mfpmath=387进行编译,并在计算和FLDL命令之前手动将FPU设置为双精度:

    fpu_control_t cw;
    _FPU_GETCW(cw);
    cw &= ~_FPU_EXTENDED;
    cw |= _FPU_DOUBLE;
    _FPU_SETCW(cw);
    

    你能解释一下,为什么在_FPU_DOUBLE模式下,FPU寄存器仍处于扩展精度模式,以及如何解决这个问题吗?

    或者只是 出现 作为长双(我在Eclipse CDT中查看寄存器),但实际上是在内部没有这些额外数字的情况下操作的?

    1 回复  |  直到 13 年前
        1
  •  2
  •   Eric Postpischil    13 年前

    编译程序时,您的数字将转换为25.3999996185302734375,因为这是 double 最接近25.399999618530273的值(使用IEEE-754 64位二进制浮点)。转换 双重的 long double 没有错误。

    当你说你可以看到0x90(%ebp)处的双精度是正确的值时,那么,如果你没有看到25.3999996185302734375,你就没有看到该位置的实际值——你使用的工具观察到的值显示不准确。

    如果你在期待 双重的 准确地代表25.399999618530273,那么你会感到失望;事实并非如此,您必须设计代码以允许这样做,或者使用 双重的 来表示这样的数字。

    您正在使用哪种工具来测量精度为000000000000001英寸的长度?那是一把非常精细的尺子,有一个非常大的放大镜和机器人增强的眼睛吗?