问题
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