INN timer code and time overflows

Heath Kehoe heath.kehoe at intermec.com
Tue Oct 3 07:29:08 UTC 2000


>
>Hm.  Could someone remind me how unsigned arithmetic works?
>
>I'm looking at the innd timer code and I think the timer values wrap in a
>long-running server.  gettime returns the number of milliseconds since the
>first time it was called (at the start of the lifetime of innd), and it's
>an unsigned int (32 bytes on most platforms).  That means the maximum
>timestamp it can return is 4294967295, or 4294967 seconds, which is about
>50 days.  After that point, I think the arithmetic would overflow.
>
>Does this just quietly work anyway?  If you subtract a very high unsigned
>number from a very low unsigned number, does it give you the right
>difference?  I can't quite wrap my mind around it.
>

Struggling to remember binary arithmetic (heh)...

It won't work, unless it's actually checking for the overflow condition.

If the difference is a large negative value you will wind up with
something that looks like a positive value.  If you know that it
overflowed, you can take the 2's-complement of that value which
(when interpreted as unsigned) will be the absolute value of the
difference.  Similarly for large positive differences, only you don't
need to complement the result; just interpret it as an unsigned value.

Problem is, C doesn't give you a way to tell if a subtraction overflowed.
You'll have to do a test afterwords, something like:

result = a - b;		/* result is signed; a and b are unsigned */
if(result > 0 && a < b) {
    /* negative overflow */
    abs_difference = -((unsigned)result);  /* abs_difference is unsigned */
} else if(result < 0 && a > b) {
    /* positive overflow */
    abs_difference = (unsigned)result;
}

of course, it's simpler to do something like this:

if(a < b) {
    abs_difference = a - b;
    sign = -1;
} else {
    abs_difference = b - a;
    sign = 1;
}


--heath




More information about the inn-workers mailing list