# [ACCEPTED]-How to detect overflow when subtracting two signed 32 bit numbers in C?-integer-overflow

Score: 14

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;
}
``````
Score: 8

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).

``````int one, two;

int result = two - one;
if ((result < two) != (one > 0))
printf("overflow");
``````
Score: 0

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.

Score: 0

There are 2 cases to consider on evaluating 2 `a-b`:

1. `a-b` may underflow, iff `b>0 && a<0` and `a-b < min == a<min+b`
2. `a-b` may overflow, iff `b<0 && a>0` and `a-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