[ACCEPTED]-How to detect overflow when subtracting two signed 32 bit numbers in C?-integer-overflow
You need to catch the overlow (or underflow) before it 2 happens. Once it happens you're in Undefined Behaviour land 1 and all bets are off.
#include <limits.h>
#include <stdio.h>
int sum_invokes_UB(int a, int b) {
int ub = 0;
if ((b < 0) && (a < INT_MIN - b)) ub = 1;
if ((b > 0) && (a > INT_MAX - b)) ub = 1;
return ub;
}
int main(void) {
printf("(INT_MAX-10) + 8: %d\n", sum_invokes_UB(INT_MAX - 10, 8));
printf("(INT_MAX-10) + 100: %d\n", sum_invokes_UB(INT_MAX - 10, 100));
printf("(INT_MAX-10) + INT_MIN: %d\n", sum_invokes_UB(INT_MAX - 10, INT_MIN));
printf("100 + INT_MIN: %d\n", sum_invokes_UB(100, INT_MIN));
printf("-100 + INT_MIN: %d\n", sum_invokes_UB(-100, INT_MIN));
printf("INT_MIN - 100: %d\n", sum_invokes_UB(INT_MIN, -100));
return 0;
}
Firstly, overflow in signed calculations 10 causes undefined behavior in C.
Secondly, forgetting 9 about UB for a second and sticking to the 8 typical overflow behavior of a 2's complement 7 machine: overflow is revealed by the fact 6 that result "moves" in the "wrong direction" from 5 the first operand, i.e when the result ends 4 up greater than the first operand with positive 3 second operand (or smaller than the first 2 operand with negative second operand).
In 1 your case
int one, two;
int result = two - one;
if ((result < two) != (one > 0))
printf("overflow");
You can do it with higher precision and 9 compare. Say you have 32-bit integers. You 8 can promote them to 64-bit integers, subtract, then 7 compare that result with itself cast to 6 32-bit and then up again to 64 bits.
I wouldn't 5 do it this way with int
, because the language 4 doesn't give you guarantees on sizes... Maybe 3 int32_t
and int64_t
from <inttypes.h>
(from C99).
If you're on Windows 2 use can use ULongSub()
etc, which returns an error 1 code on overflow.
There are 2 cases to consider on evaluating 2 a-b
:
a-b
may underflow, iffb>0 && a<0
anda-b < min == a<min+b
a-b
may overflow, iffb<0 && a>0
anda-b > max == -b>max-a
This leads us on simplifying the a
case 1 to
#include <limits.h>
int sub_invokes_UB(int a, int b) {
if ((b > 0) && (a < INT_MIN + b)) ub = 1; // error
if ((b < 0) && (a > INT_MAX + b)) ub = 1; // error
return 0; // ok
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.