我有兩個有符號整數,我想減去它們。我需要知道它是否溢出。如何在C中減去兩個帶符號的32位數字時檢測溢出?
int one;
int two;
int result = two-one;
if (OVERFLOW) {
printf("overflow");
} else {
printf("no overflow");
}
就是這樣的。有沒有一個好的方法來做到這一點?
我有兩個有符號整數,我想減去它們。我需要知道它是否溢出。如何在C中減去兩個帶符號的32位數字時檢測溢出?
int one;
int two;
int result = two-one;
if (OVERFLOW) {
printf("overflow");
} else {
printf("no overflow");
}
就是這樣的。有沒有一個好的方法來做到這一點?
首先,溢出簽署計算導致未定義行爲C.
其次,忘記了UB一秒鐘,堅持2的補機的典型的溢出行爲:溢出是導致這一事實表明「向第一個操作數「錯誤的方向」移動,即當結果大於第一個操作數的正的第二個操作數(或小於第一個操作數的負的第二個操作數)時。
在你的情況
int one, two;
int result = two - one;
if ((result < two) != (one > 0))
printf("overflow");
您可以以更高的精度進行比較。假設你有32位整數。您可以將它們提升爲64位整數,然後減去,然後將該結果與自身進行比較,轉換爲32位,然後再轉換爲64位。
我不會int
做這種方式,因爲語言不給你保證在大小......也許int32_t
和int64_t
從<inttypes.h>
(從C99)。
如果你在Windows上使用可以使用ULongSub()
等,它會在溢出時返回一個錯誤代碼。
你需要趕上過低(或下溢)它發生之前。一旦發生這種情況,你在未定義的行爲土地和所有投注都關閉。
#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;
}
如果'int result = two - one;'溢出(或下溢),您將進入Undefined Behavior land併發生任何事情。 – pmg 2009-10-27 21:49:20
這是我在迴應的第一句中明確指出的內容。 (儘管術語「下溢」在傳統意義上不適用於此)。 – AnT 2009-10-27 21:53:21
我喜歡這個答案,但正如你所記錄的那樣 - 未定義的行爲。如果可以安全地假設結果會在'錯誤的方向'上'移動'? – 2009-10-27 21:56:52