5

重複の可能性:
C/C++ で整数オーバーフローを検出する最良の方法

Cで関数を書いていますが、質問は一般的です。この関数は 3 つの整数を取り、これらの 3 つの整数に関する情報を返します。

ここで私が疑う問題は、整数が最大になる可能性があり、これがオーバーフローを引き起こす可能性があることです。

例: 可能な最大値として a を渡し、b が 1 から最大までの任意の値を指定できる場合、この場合、式 (a+b)>c は if 条件でオーバーフローを引き起こしますか? もしそうなら、どうすればそれを処理できますか?

私の解決策は、長い整数を一時変数として保持して a+b の値を保持し、それを式で使用することでしたが、それは汚い方法に聞こえます。

このスニペットを参照してください。

int
triangle_type(int a, int b, int c) {
    if (!((a+b)>c)&&((b+c) > a)&&((a+c>b))) {
        return -1;
    }
}
4

2 に答える 2

3

現在のプロセッサでは、整数での実際のシグナリング オーバーフローはありません。したがって、32 ビット プロセッサでは、ビット レベルで 2^32 を法とする整数演算が行われます。2 つの -s を加算しintて「オーバーフロー」が発生すると、ステータス レジスタにオーバーフロー (またはキャリー) ビットが設定されます (算術演算はモジュラス 2^32 で行われます)。(通常はそうであるように) そのオーバーフロー ステータス ビットをテストする機械語命令がない場合、何も起こりません。

そのため、オーバーフローが原因で制御フローが変更されることはありません (通常は、SIGEMT シグナルなどのゼロ除算で変更されます)。

C でオーバーフローのケースを移植可能にキャッチしたい場合は、たとえば、2 つの正のint-s の合計が正のままであることをテストできます。(負の場合、オーバーフローが発生しました)。

bignumsにも興味があるかもしれません。たとえば、gmp ライブラリを使用してください。<stdint.h>また、慎重int32_tint64_t明示的なキャストを使用して使用することもできます。最後に、(ほとんどのコーダーがそうであるように) その問題を無視することを選択できます。

注: Jonathan が気づいたように、未定義の動作または未指定の動作のケースに陥る可能性があります。本当に気にするなら、bignums を使ってください。ただし、まったく気にしないことを選択することもできます。

于 2012-10-20T05:51:01.420 に答える
0

あなたはこのようなことをすることができます

// returns true if a+b > c
inline int safe_sum_greater (int a, int b, int c) {
   int a1 = a / 4; int a2 = a % 4;
   int b1 = b / 4; int b2 = b % 4;
   int c1 = c / 4; int c2 = c % 4;
   int s2 = a2 + b2;

   int s1 = a1 + b1 + s2 / 4;
   s2 = s2 % 4;
   return (s1 > c1) || ( (s1 == c1) && (s2 > c2) );
}

ビット単位の演算のみが使用されるため、パフォーマンスは悪くありません。負の数についてはあまり考えていませんので、注意して使用してください。

于 2012-10-20T06:42:52.580 に答える