How to detect overflow when subtracting two signed 32 bit numbers in C?

11,257

Solution 1

Firstly, overflow in signed calculations causes undefined behavior in C.

Secondly, forgetting about UB for a second and sticking to the typical overflow behavior of a 2's complement machine: overflow is revealed by the fact that result "moves" in the "wrong direction" from the first operand, i.e when the result ends up greater than the first operand with positive second operand (or smaller than the first operand with negative second operand).

In your case

int one, two;

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

Solution 2

You need to catch the overlow (or underflow) before it happens. Once it happens you're in Undefined Behaviour land 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;
}
Share:
11,257
Murph
Author by

Murph

Updated on June 16, 2022

Comments

  • Murph
    Murph about 2 years

    I've got two signed integers, and i'd like to subtract them. I need to know if it overflowed.

    int one;
    int two;
    int result = two-one;
    
    if (OVERFLOW) {
        printf("overflow");
    } else {
        printf("no overflow");
    }
    

    Something like that. Is there a good way to do this?