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