ctime.htimespec

Subtraction of long in C loses precision?


I'm sure the answer is simple, but I don't quite get it. I'm trying to calculate the delta between two struct timespec using this code:

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);

However, the output is always something like Elapsed time: 0.300876000 seconds. which seems to indicate that I'm losing the last three digits of the nanoseconds (since those shouldn't always be zero). Can someone point out what's causing that?


Solution

  • Elapsed time: 0.300876000 seconds. which seems to indicate that I'm losing the last three digits of the nanoseconds (since those shouldn't always be zero). Can someone point out what's causing that?

    The code's clock reported precision is 1000 ns. @John Bollinger @rici

    and/or

    diff.tv_sec is not necessarily a long. Use a matching specifier.

    // 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);
    

    Also, incorrect "borrow" math when updating the ndiff.

    ndiff = finish.tv_nsec - start.tv_nsec;
    if (ndiff < 0) {
      diff.tv_sec--;
      // ndiff = 1L - ndiff;
      ndiff += 1000000000;
    }
    

    Even better, drop the int diff variable.

    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;
    }
    

    Should finish occur before start, then other code may be desired to keep the 2 members of diff with the same sign.