在C中减去long会丢失精度吗?

时间:2017-11-06 22:09:35

标签: c time.h timespec

我确信答案很简单,但我不太清楚。我正在尝试使用以下代码计算两个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 :(得分:2)

  

经过时间:0.300876000秒。这似乎表明我失去了纳秒的最后三位数(因为那些不应该总是为零)。有人可以指出导致这种情况的原因吗?

代码的时钟报告精度为1000 ns。 @John Bollinger @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);

另外,不正确&#34;借&#34;更新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应该diff出现,可能需要其他代码来保持{{1}}的2个成员具有相同的符号。