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

杀马特。学长 韩版系。学妹 提交于 2020-02-23 06:10:25

问题


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?


回答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");



回答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;
}



回答3:


You can do it with higher precision and compare. Say you have 32-bit integers. You can promote them to 64-bit integers, subtract, then compare that result with itself cast to 32-bit and then up again to 64 bits.

I wouldn't do it this way with int, because the language doesn't give you guarantees on sizes... Maybe int32_t and int64_t from <inttypes.h> (from C99).

If you're on Windows use can use ULongSub() etc, which returns an error code on overflow.



来源:https://stackoverflow.com/questions/1633561/how-to-detect-overflow-when-subtracting-two-signed-32-bit-numbers-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!