P
Peter Nilsson
There's no idiom since people don't do it that often.
But observe the maths...
INT_MIN <= a + b <= INT_MAX
<=> INT_MIN - b <= a <= INT_MAX - b
So, for signed integers...
/* summation overflow */
if (b < 0) { if (a < INT_MIN - b) overflow(); }
else { if (INT_MAX - b < a) overflow(); }
/* subraction overflow */
if (b < 0) { if (INT_MAX + b < a) overflow(); }
else { if (a < INT_MIN + b) overflow(); }
There is no overflow of unsigned types with a rank of int
or above. [Lower ranks may promote to int in which case
overflow is possible.] But the quoted range check works by
virtue of modulo arithmetic necessary for unsigned int.
It's really quite simple to see. Consider a + b mod 2^n.
Now what non-negative number b would you need to add to a
to make the result larger than a (modulo 2^n)?
But observe the maths...
INT_MIN <= a + b <= INT_MAX
<=> INT_MIN - b <= a <= INT_MAX - b
So, for signed integers...
/* summation overflow */
if (b < 0) { if (a < INT_MIN - b) overflow(); }
else { if (INT_MAX - b < a) overflow(); }
/* subraction overflow */
if (b < 0) { if (INT_MAX + b < a) overflow(); }
else { if (a < INT_MIN + b) overflow(); }
So it is guaranteed by the C standard that in case of
overfllow the result of sum will be less then either
operand?
There is no overflow of unsigned types with a rank of int
or above. [Lower ranks may promote to int in which case
overflow is possible.] But the quoted range check works by
virtue of modulo arithmetic necessary for unsigned int.
It's really quite simple to see. Consider a + b mod 2^n.
Now what non-negative number b would you need to add to a
to make the result larger than a (modulo 2^n)?