I’m debugging an ANSI C program run on 64-bit Linux CentOS 5.7 using gcc44 and gdb. I have the following loop in the program:
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);
}
where time_sec, dt, and UI0_offset are doubles. The relevant gdb session is:
(gdb) p time_sec[1]
$2 = 2.9874137906250006e-15
(gdb) p ( 10326 ) * dt - UI0_offset
$3 = 2.9874137906120759e-15
Why are $2 and $3 different numbers? The $2=time_sec[1] is computed by the c program, whereas $3 is the same equation, but computed in gdb.
I’m porting a Matlab algorithm to C and Matlab (run on a different machine) matches the gdb number $3 exactly, and I need this precision. Anyone know what could be going on here, and how to resolve?
UPDATE: After some debugging, it seems the difference is in the value of UI0_offset. I probed gdb to reveal a few extra digits for this variable (note: anyone know a better way to see more digits in gdb? I tried an sprintf statement but couldn’t get it to work):
(gdb) p UI0_offset -1e-10
$5 = 3.2570125862093849e-12
I then inserted the printf() code in the loop shown in the original posting above, and when it runs in gdb it shows:
time_sec[1] = 2.987413790625001e-15, dt = 1.000000000000000e-14,
UI0_offset = 1.0325701258620937565691357e-10
Thus, to summarize:
1.032570125862093849e-10 (from gdb command line, the correct value)
1.0325701258620937565691357e-10 (from program's printf statement, NOT correct value)
Any theories why the value for UI0_offset is different between gdb command line and the program running in gdb (and, how to make the program agree with gdb command line)?
I’m not sure if the x64 architecture contains the same 80-bit (long double) FP registers as the x86 does, but oftentimes results like these in the x86 world arise when intermediate results (i.e. the first multiplication) remain in the 80-bit registers rather than getting flushed back to cache/RAM. Effectively part of your calculation is done at higher precision, thus the differing results.
GCC has an option (
-ffloat-storeif my memory serves) that will cause intermediate results to be flushed back to 64-bit precision. Try to enable that and see if you match the GDB/Matlab result.