- From: Ingo Krabbe <ikrabbe@earthling.net>
- Date: Fri, 23 Nov 2001 20:15:41 +0100 (CET)
- To: Phil Nitschke <Phil.Nitschke@youramigo.com>
- cc: <www-lib@w3.org>
> /* ... */ > > Platform: > > Linux strife 2.4.4 #1 Tue May 22 11:04:41 CST 2001 i686 unknown > > Source: > > #include <stdio.h> > #include <stdlib.h> > #include <time.h> > #include <sys/time.h> > > typedef unsigned long ms_t; > > ms_t HTGetTimeInMillis2 (const struct timeval * tp) > { > return(tp->tv_sec * 1000) + (tp->tv_usec / 1000); > } > > void do_tests (struct timeval * tp) > { > ms_t prev_time, new_time; > > prev_time = HTGetTimeInMillis2 (tp); > tp->tv_sec += 3; > > for (;;) > { > tp->tv_sec++; > new_time = HTGetTimeInMillis2 (tp); > > if (new_time <= prev_time) > break; > > prev_time = new_time; > } > > printf ("Overflow broke at %s Performing comparison of: %lu and %lu !!\n", > ctime ((time_t *)&tp->tv_sec), new_time, prev_time); > } > > int main (void) > { > int i; > struct timeval tp; > > gettimeofday(&tp, NULL); > > for (i = 0; i < 10; i++) > do_tests (&tp); > > exit (0); > } > These result are exactly the results I meant to be easily resolved by scale discussion: Overflow broke at Wed Dec 26 08:25:14 2001 Performing comparison of: 418 and 4294966714 !! Overflow broke at Thu Feb 14 01:28:01 2002 Performing comparison of: 122 and 4294966418 !! Overflow broke at Thu Apr 4 17:30:49 2002 Performing comparison of: 826 and 4294967122 !! Overflow broke at Fri May 24 10:33:36 2002 Performing comparison of: 530 and 4294966826 !! Overflow broke at Sat Jul 13 03:36:23 2002 Performing comparison of: 234 and 4294966530 !! Overflow broke at Sat Aug 31 20:39:11 2002 Performing comparison of: 938 and 4294967234 !! Overflow broke at Sun Oct 20 13:41:58 2002 Performing comparison of: 642 and 4294966938 !! Overflow broke at Mon Dec 9 07:44:45 2002 Performing comparison of: 346 and 4294966642 !! Overflow broke at Tue Jan 28 00:47:32 2003 Performing comparison of: 50 and 4294966346 !! Overflow broke at Tue Mar 18 17:50:20 2003 Performing comparison of: 754 and 4294967050 !! The second number is always near to 2^32 = 4294967296 The first number is always near to 0 ! Let's take a milliseconds scale of 3600 seconds = 1 day. If two values are farer away from each other we DEFINE that we CANNOT express this INTERVAL in milliseconds but have to take more care for them: ms_t HTGetTimeInMillis /* ... */ struct tm X, Y; /* long range interval */ ms_t a, b; /* interval */ struct timeval t0, t1; /* other time coordinates */ X = get_tm_from_timeval( t0 ); a = HTGetTimeInMillis2( t0 ); for ( ;; ) { ms_t distance; int overflow_type = 0; t1 = gettimeofday(); b = HTGetTimeInMillis2( t1 ); distance = 0; if ( a < b ) /* first ok */ { distance = b - a; if ( distance > 3600000 ) { distance %= 3600000; overflow_type = 1; } } else if ( a > b ) { overflow_type = 2; distance = ((ms_t)(-1))-a + b; /* have a forgot 1 ms ? */ if ( distance > 3600000 ) { distance %= 3600000; overflow_type = 3; } } if ( overflow_type & 1 ) { switch ( overflow_type ) { /* think about long range distances, in most cases we don't need to do that, since our problem simply doesn't allow such intervals --> we have a real error condition */ } } else { /* ok, proceed */ } } Here you can see that on ms_t overflow we simply proceed with ((ms_t)(-1)) - a + b which will fit again in the unsigned type ! We can do this since we know that !!! a IS SMALLER THAN b !!! Real problems are overflow_type 1 and 3 since they break our previous definition of one day intervals. Our timeout condition for example is quite over reached, so we (MAY) need a special handling. If you really want to calculate an exact time interval you can now proceed with a struct tm calculation with which you can really can express the age of Napoleon in years, days and milliseconds :-) CU INGO
Received on Friday, 23 November 2001 14:15:23 UTC