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_sec
andtv_nsec
values 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
double
value 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 timespec
values is one task; converting astruct timespec
value to an appropriatedouble
is a separate task. When you can split things into separate tasks, you should.I often pass
struct timespec
values 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_sec
member of astruct timespec
contains an integer number of seconds, and thetv_nsec
contains the fractional part of a second expressed as a number of nanoseconds (0 to 999,999,999). It requires care in printing thetv_nsec
value; you need a format such as%.9ld
to print 9 digits with leading zeros, and the type islong
. To print microseconds, divide thetv_nsec
value by 1,000 and change 9 to 6; to print milliseconds, divide by 1,000,000 and change 9 to 3. Beware negative values!