gpt4 book ai didi

qt - 糟糕的浮点魔法

转载 作者:行者123 更新时间:2023-12-02 07:09:08 26 4
gpt4 key购买 nike

我有一个奇怪的 float 问题。

背景:

我正在为具有大整数算术协处理器的 8 位处理器实现 double (64 位)IEEE 754 浮点库。为了测试这个库,我将我的代码返回的值与英特尔的浮点指令返回的值进行比较。这些并不总是一致,因为英特尔的浮点单元在内部以 80 位格式存储值,带有 64 位尾数。

示例(全部为十六进制):

X = 4C816EFD0D3EC47E:
偏置指数 = 4C8(真指数 = 1C9),尾数 = 116EFD0D3EC47E

Y = 449F20CDC8A5D665:
偏置指数 = 449(真实指数 = 14A),尾数 = 1F20CDC8A5D665

计算 X * Y

尾数的乘积为 10F5643E3730A17FF62E39D6CDB0,四舍五入为 53(十进制)位时为 10F5643E3730A1(因为 7FF62E39D6CDB0 的最高位为零)。所以结果中正确的尾数是10F5643E3730A1。

但如果使用 64 位尾数进行计算,则 10F5643E3730A17FF62E39D6CDB0 会四舍五入为 10F5643E3730A1800,当再次四舍五入为 53 位时,它会变成 10F5643E3730A2。最低有效位从 1 变为 2。

总结:我的库返回正确的尾数 10F5643E3730A1,但英特尔硬件返回(正确)10F5643E3730A2,因为它的内部 64 位尾数。

问题:

现在,这是我不明白的地方:有时英特尔硬件会在尾数中返回 10F5643E3730A1!我有两个程序,一个 Windows 控制台程序和一个 Windows GUI 程序,它们都是由 Qt 使用 g++ 4.5.2 构建的。控制台程序按预期返回 10F5643E3730A2,但 GUI 程序返回 10F5643E3730A1。他们使用的是相同的库函数,它具有三个指令:

fldl   -0x18(%ebp)
fmull -0x10(%ebp)
fstpl 0x4(%esp)

这三个指令在两个程序中计算出不同的结果。 (我已经在调试器中逐步完成了它们。)在我看来,这可能是 Qt 在其 GUI 启动代码中配置 FPU 所做的事情,但我找不到任何有关的文档这。有人知道这里发生了什么吗?

最佳答案

函数的指令流和输入并不能唯一地确定其执行。您还必须考虑处理器执行时已经建立的环境。

如果您检查 x87 控制字,您会发现它被设置为两种不同的状态,对应于您观察到的两种行为。其中,精度控制 [位 9:8] 已设置为 10b(53 位)。在另一个中,它被设置为 11b(64 位)。

至于什么 正在建立非默认状态,它可能是在执行您的代码之前该线程中发生的任何事情。任何被拉入的库都可能是可疑的。如果你想做一些考古,确凿的证据通常是 fldcw 指令(尽管控制字也可以由 fldenvfrstorfinit

关于qt - 糟糕的浮点魔法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7848524/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com