Вычитание long в C теряет точность?
Я уверен, что ответ прост, но я не совсем понимаю. Я пытаюсь вычислить дельту между двумя struct timespec
используя этот код:
struct timespec start, finish, diff;
int ndiff;
/* Structs are filled somewhere else */
diff.tv_sec = finish.tv_sec - start.tv_sec;
ndiff = finish.tv_nsec - start.tv_nsec;
if (ndiff < 0) {
diff.tv_sec--;
ndiff = 1L - ndiff;
}
diff.tv_nsec = ndiff;
printf("Elapsed time: %ld.%ld seconds.\n", diff.tv_sec, diff.tv_nsec);
Однако на выходе всегда что-то вроде Elapsed time: 0.300876000 seconds.
который, кажется, указывает на то, что я теряю последние три цифры наносекунд (поскольку они не всегда должны быть равны нулю). Кто-то может указать, что это вызывает?
1 ответ
Истекшее время: 0,300876000 секунд. который, кажется, указывает на то, что я теряю последние три цифры наносекунд (поскольку они не всегда должны быть равны нулю). Кто-то может указать, что это вызывает?
Точность кода часов равна 1000 нс. @ Джон Боллинджер @rici
и / или
diff.tv_sec
не обязательно long
, Используйте соответствующий спецификатор.
// printf("Elapsed time: %ld.%ld seconds.\n", diff.tv_sec, diff.tv_nsec);
// Also insure fraction is printed with 9 digits
printf("Elapsed time: %lld.%09ld seconds.\n", (long long) diff.tv_sec, diff.tv_nsec);
Кроме того, неверная математика "позаимствовать" при обновлении ndiff
,
ndiff = finish.tv_nsec - start.tv_nsec;
if (ndiff < 0) {
diff.tv_sec--;
// ndiff = 1L - ndiff;
ndiff += 1000000000;
}
Еще лучше бросьте int diff
переменная.
diff.tv_sec = finish.tv_sec - start.tv_sec;
diff.tv_nsec = finish.tv_nsec - start.tv_nsec;
if (diff.tv_nsec < 0) {
diff.tv_sec--;
diff.tv_nsec += 1000000000;
}
Должен finish
происходят раньше start
тогда может потребоваться другой код, чтобы сохранить 2 члена diff
с таким же знаком.