This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: strange bug in gettimeofday function
--On 16 February 2007 04:12 +0300 Andrew Makhorin <mao@gnu.org> wrote:
double get_time(void)
{ struct timeval tv;
gettimeofday(&tv, NULL);
return (double)tv.tv_sec + 1e-6 * (double)tv.tv_usec;
}
I would be suspicious of floating-point rounding errors here for the
original problem you described. Why don't you try a test case that just
checks if one tv is ever less than a previous tv, without the
conversions.
But then I would like to know why comparison of two floating-point
numbers leads to different results: t0 is *exactly* the same as t1,
nevertheless the condition t0 > t1 is true (sometimes). That is the
question.
The multiplier 1e-6 cannot be represented exactly in binary floating point.
Therefore the internal representation of your tv_usec will always be
subject to rounding errors, maybe upwards or maybe downwards. Therefore,
the result of this function will never be an accurate representation of the
time as returned by struct timeval. The impact of the rounding error will
depend on at what point the internal 80-bit value in the processor is
rounded to 64 bits for storage as a double.
If you really must do this (and it is not advised) you might do better by
multiplying tv_sec by 1e6 then adding tv_usec unscaled, so that the
floating point variable holds an integer number of microseconds.
Also, if tv_sec is large, there might be significant loss of precision as
tv_sec and tv_usec are shifted 6 decimal places (about 20 binary places)
relative to each other in the mantissa.
Floating point representation should never be used for something for which
you need an accurate value, or where you require to test for two things
being equal. You have a struct which conveys the time accurately: why not
use that? It is trivial to write functions which compare two timevals for
equality, or yield the difference between two timevals.
Another possible factor to bear in mind has already been alluded to:
Windows clock slew. Because PC clocks do not keep accurate time, Windows
calibrates the internal clock against an external source (in XP, this is by
default time.microsoft.com). By comparison of the two clocks, Windows
calculates a slew by which it occasionally adjusts the PC clock to keep the
time of day in step with the external source. I do not know whether this
factor is relevant to the data returned by gettimeofday().
--
Robin Walker (Junior Bursar), Queens' College, Cambridge CB3 9ET, UK
rdhw@cam.ac.uk http://www.queens.cam.ac.uk/ Tel:+44 1223 335528
Attachment:
p7s00000.p7s
Description: S/MIME cryptographic signature