double timespec_delta2milliseconds(struct timespec *last, struct timespec *previous)
{
return (last->tv_sec - previous->tv_sec) + (last->tv_nsec - previous->tv_nsec)*pow(10,-3);
}
This function computes the difference (last - previous) and returns the result expressed in milliseconds as a double. I tried a lot of different ways but if I don't do like this i receve in output segmentation fault. I think that this solution works but it's wrong, someone can help me ?
You need two functions:
sub_timespec(), which calculates the difference between two time spec values, andtimespec_as_milliseconds(), which returns the number of milliseconds in a time spec value as an integer.If you want to round the milliseconds, it gets trickier because you have to worry about carries and negative numbers and so on. You should not encounter a timespec value where the
tv_secandtv_nsecvalues have opposite signs (zeros aren't a problem).In your code, adding
pow(10, -3)mixes floating point arithmetic with integer arithmetic — usually not a good idea.If you want a
doublevalue with up to 3 decimal places of fractional seconds, then you need:The first division is (deliberately) integer division; the second gives a floating-point value. Again, rounding has problems with carrying and so on.
Your function then becomes:
You can use an extra value in the function so it is easier to print the value returned in a debugger:
double rv = timespec_to_double_milliseconds(delta); return rv;.The key idea, though, is to do separate tasks in separate functions. Taking the difference between two
struct timespecvalues is one task; converting astruct timespecvalue to an appropriatedoubleis a separate task. When you can split things into separate tasks, you should.I often pass
struct timespecvalues by value rather than pointer. The structure size is typically small enough that it is not a stress on the stack or registers. I return them by value too, which simplifies memory management — YMMV.And, just in case it isn't clear, the
tv_secmember of astruct timespeccontains an integer number of seconds, and thetv_nseccontains the fractional part of a second expressed as a number of nanoseconds (0 to 999,999,999). It requires care in printing thetv_nsecvalue; you need a format such as%.9ldto print 9 digits with leading zeros, and the type islong. To print microseconds, divide thetv_nsecvalue by 1,000 and change 9 to 6; to print milliseconds, divide by 1,000,000 and change 9 to 3. Beware negative values!