2

我正在调查一个在 static_casting long double to double 时 gcc 和 gdb 的奇怪行为的问题。我有类似以下代码的内容:

const double xDelta = 60.0;
int xSplits = 3;
const long double xStepL = static_cast<long double>(xSplits) / xDelta;
const double xStep = static_cast<double>(xStepL);

基本上它除以 3/60,所以结果应该是 0.05。使用简单double值操作时,值xStep0.050000000000000003,因此决定使用更高精度的 12 字节long doublexStepL上例中的值为0.05000000000000000000067762635780344。当将此值转换回 时double,实际上0.050000000000000003又是。但是,当使用 gdb 检查该值时,它会打印以下内容:

(gdb) p xStep
$1 = 0.050000000000000003
(gdb) p static_cast<double>(xStepL)
$2 = 0.049999999999999996

知道为什么结果不同吗?我真的希望它是第二个。任何人都知道如何实现这一目标?

顺便说一句,我使用的是 GCC 4.3.4 和 GDB 7.2.50。

4

2 回答 2

2

这看起来像 gdb 中的一个错误。

long double转换 from to的指令doublefldt(10 字节浮点加载)后跟fstpl(8 字节浮点存储)。当您执行降低精度的浮点存储时,它将对操作数进行四舍五入,从0.050000000000000000000677626357803440.050000000000000003。看起来 gdb 正在截断操作数,从0.050000000000000000000677626357803440.049999999999999996。在浮点十六进制中:

0x1.99999999999999999999ap-5 -> 0x1.999999999999ap-5 (gcc, correct)
0x1.99999999999999999999ap-5 -> 0x1.9999999999999p-5 (gdb, incorrect)

讨论表明这已在最新版本的 gdb (7.4.50) 中得到修复。

于 2012-08-02T14:01:06.930 回答
1

我相信问题是static_casts没有被调用相同的值。代码中的值使用更高精度的寄存器值调用,而从 gdb 调用的值将在内存中使用 long double。我不确定允许编译器执行此操作的确切位置,但我猜这是一个 - 所以答案最终可能会因一个 elp 而不同。

于 2012-08-02T12:50:22.613 回答