- 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