(1)があります:
// assume x,y are non-negative
if(x > max - y) error;
そして(2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
どちらが好ましいか、より良い方法があります。
(1)があります:
// assume x,y are non-negative
if(x > max - y) error;
そして(2):
// assume x,y are non-negative
int sum = x + y;
if(sum < x || sum < y) error;
どちらが好ましいか、より良い方法があります。
整数オーバーフローは、C における「未定義の動作」の標準的な例です (符号なし整数の操作は決してオーバーフローしないことに注意してください。代わりにラップアラウンドするように定義されています)。これは、 を実行したx + y
後にオーバーフローした場合、すでにホースがかかっていることを意味します。チェックするには遅すぎます。プログラムはすでにクラッシュしている可能性があります。ゼロ除算をチェックするようなものだと考えてください。除算が実行されてからチェックするのを待っていては、手遅れです。
したがって、これは、方法 (1) がそれを行う唯一の正しい方法であることを意味します。には、からmax
使用できます。INT_MAX
<limits.h>
x
and/orが負になる可能性がある場合y
、事態はさらに難しくなります。テスト自体がオーバーフローを引き起こさないようにテストを実行する必要があります。
if ((y > 0 && x > INT_MAX - y) ||
(y < 0 && x < INT_MIN - y))
{
/* Oh no, overflow */
}
else
{
sum = x + y;
}
unsigned
実際には、整数と算術演算でのみオーバーフローをチェックできます。
unsigned a,b,c;
a = b + c;
if (a < b) {
/* overflow */
}
符号付き整数によるオーバーフローの動作はCでは定義されていませんが、ほとんどのマシンで使用できます
int a,b,c;
a = b + c;
if (c < 0 ? a > b : a < b) {
/* overflow */
}
これは、あらゆる種類の飽和演算を使用するマシンでは機能しません
そのうちの1つをチェックするだけです。x + yがオーバーフローした場合、xとyの両方よりも小さくなります。したがって:
int sum = x + y;
if (sum < x) error;
十分なはずです。
次のサイトには、整数のオーバーフローに関する情報がたくさんあります。
負の数を処理する場合は、次のように拡張できます。
int sum = x + y;
if (y >= 0) {
if (sum < x) error;
} else {
if (sum > x) error;
}