为什么从我的c程序打印的变量的值与gdb打印的变量的值不同?

时间:2011-12-09 00:53:05

标签: c gdb

我正在使用gcc44和gdb调试在64位Linux CentOS 5.7上运行的ANSI C程序。我在程序中有以下循环:

for (ii = 1; ii < 10001; ii++) {
    time_sec[ii] = ( 10326 ) * dt - UI0_offset;  /* in seconds */ 
    printf("\ntime_sec[%d] = %16.15e, dt = %16.15e, UI0_offset = %26.25e\n", 
           ii, time_sec[ii], dt, UI0_offset);
}

其中time_sec,dt和UI0_offset是双倍的。相关的gdb会话是:

(gdb) p time_sec[1]
$2 = 2.9874137906250006e-15
(gdb) p ( 10326 ) * dt - UI0_offset
$3 = 2.9874137906120759e-15

为什么$ 2和$ 3不同的数字? $ 2 = time_sec [1]由c程序计算,而$ 3是相同的等式,但是以gdb计算。

我将Matlab算法移植到C和Matlab(在不同的机器上运行)完全匹配gdb编号$ 3,我需要这个精度。任何人都知道这里会发生什么,以及如何解决?

更新:经过一些调试后,似乎差异在于UI0_offset的值。我探测gdb为这个变量揭示了一些额外的数字(注意:有人知道更好的方法来查看gdb中的更多数字吗?我尝试了一个sprintf语句,但无法让它工作):

(gdb) p UI0_offset -1e-10
$5 = 3.2570125862093849e-12

然后我将printf()代码插入上面原始帖子中显示的循环中,当它在gdb中运行时显示:

time_sec[1] = 2.987413790625001e-15, dt = 1.000000000000000e-14, 
UI0_offset = 1.0325701258620937565691357e-10

因此,总结一下:

1.032570125862093849e-10 (from gdb command line, the correct value)
1.0325701258620937565691357e-10 (from program's printf statement, NOT correct value)

任何理论为什么UI0_offset的值在gdb命令行和在gdb中运行的程序之间是不同的(以及如何使程序与gdb命令行一致)?

1 个答案:

答案 0 :(得分:4)

我不确定x64架构是否包含与x86相同的80位(长双)FP寄存器,但是当中间结果(即第一次乘法)保留时,x86世界中的结果通常会出现80位寄存器而不是刷新回缓存/ RAM。有效地计算的一部分是以更高的精度完成的,因此会产生不同的结果。

GCC有一个选项(-ffloat-store,如果我的内存服务),这将导致中间结果被刷新回64位精度。尝试启用它,看看你是否匹配GDB / Matlab结果。