почему значение переменной, напечатанной из моей программы на c, отличается от значения, напечатанного в gdb? - PullRequest
1 голос
/ 09 декабря 2011

Я отлаживаю программу ANSI C, запущенную на 64-битном Linux CentOS 5.7 с использованием gcc44 и gdb.У меня есть следующий цикл в программе:

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 number $ 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 Ответ

4 голосов
/ 09 декабря 2011

Я не уверен, что архитектура x64 содержит те же 80-битные (длинные двойные) регистры FP, что и x86, но часто результаты, подобные этим, в мире x86 возникают, когда промежуточные результаты (т.е. первое умножение) остаются в 80-битные регистры, а не сбрасываются обратно в кеш / ОЗУ. Фактически часть ваших расчетов выполняется с более высокой точностью, поэтому результаты отличаются.

У GCC есть опция (-ffloat-store, если моя память работает), которая приводит к сбросу промежуточных результатов с 64-битной точностью. Попробуйте включить это и посмотрите, соответствует ли вам результат GDB / Matlab.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...