strange bug in gettimeofday function

Robin Walker rdhw@cam.ac.uk
Fri Feb 16 11:28:00 GMT 2007


--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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pkcs7-signature
Size: 4031 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20070216/d431eb24/attachment.p7s>


More information about the Cygwin mailing list