This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]