web-dev-qa-db-ja.com

C#で整数オーバーフローを処理する最良の方法?

整数オーバーフローの処理は一般的なタスクですが、C#でそれを処理する最良の方法は何ですか?他の言語よりも簡単にするための構文糖はありますか?それとも本当にこれが最善の方法ですか?

int x = foo();
int test = x * common;
if(test / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");
43
dreadwail

これを頻繁に使用する必要はありませんでしたが、 checked キーワードを使用できます。

int x = foo();
int test = checked(x * common);

オーバーフローするとランタイム例外が発生します。 MSDNから:

チェックされたコンテキストでは、式が出力先の型の範囲外の値を生成する場合、結果は式が定数か非定数かによって異なります。定数式はコンパイル時にエラーを引き起こしますが、非定数式は実行時に評価され、例外が発生します。

また、別のC#キーワードuncheckedがあることも指摘しておきます。これは、もちろんcheckedの反対を行い、オーバーフローを無視します。 uncheckedはデフォルトの動作のように見えるので、いつ使用するのか疑問に思われるかもしれません。まあ、checkeduncheckedの外の式の処理方法を定義するC#コンパイラオプションがあります: / checked 。プロジェクトの高度なビルド設定で設定できます。

チェックする必要のある式がたくさんある場合、最も簡単なことは、実際には/checkedビルドオプションを設定することです。次に、オーバーフローする式は、uncheckedでラップしない限り、実行時例外が発生します。

103
Michael Petito

以下をお試しください

int x = foo();
try {
  int test = checked (x * common);
  Console.WriteLine("safe!");
} catch (OverflowException) {
  Console.WriteLine("oh noes!");
}
19
JaredPar

最良の方法は、Micheal Saidのようです-Checkedキーワードを使用します。これは次のように行うことができます:

int x = int.MaxValue;
try   
{
    checked
    {
        int test = x * 2;
        Console.WriteLine("No Overflow!");
    }
}
catch (OverflowException ex)
{
   Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}
7
Chinjoo

古いスレッドですが、これに遭遇しました。例外を使いたくありませんでした。私が終わったのは:

long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
    do whatever you want with the overflow
return((int)a);
4
YourUncleBob

simplest wayがbest wayである場合があります。私はあなたが書いたものを書くためのより良い方法を考えることはできませんが、あなたはそれを短くすることができます:

_int x = foo();

if ((x * common) / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");
_

foo()を3回呼び出すのはばかげているので、x変数を削除しなかったことに注意してください。

4
Alon Gubkin

だから、私は事実の後ずっとこれに遭遇し、それはほとんど私の質問に答えましたが、私の特定のケースでは(他の誰かが同じ要件を持っている場合)、私はsigned intの正の値をあふれさせるだけのものにほしかったint.MaxValue

int x = int.MaxValue - 3;
int someval = foo();

try
{
   x += someval;
}

catch (OverflowException)
{
   x = int.MaxValue;
}
0
Jesse Williams