整数のオーバーフローが例外にならない理由
int型の範囲(約-21億〜21億)を超える計算をしても、既定では例外にならず値が折り返ります。
なぜエラーが出ないのか
出力: -2147483648
(エラーなし)- C#は何も報告しません。文法として正しいためです
出力: -2147483648- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 class Program { 2 static void Main(string[] args) { 3 int max = int.MaxValue; 4 int result = max + 1 ; ^ 5 System.Console.WriteLine(result); 6 } 7 }
出力: -2147483648
intの範囲は約21億までです。それを超えると例外にはならず、静かに最小値側へ折り返します(既定のuncheckedコンテキストのため)。
直し方: 1 を 0 にします。
広告
広告スロット(未設定)
パターン2
1 class Program { 2 static void Main(string[] args) { 3 int max = int.MaxValue; 4 int result = max * 2 ; ^ 5 System.Console.WriteLine(result); 6 } 7 }
出力: -2
掛け算でも同じことが起きます。桁あふれは例外を投げず、そのまま計算を続けてしまいます。
直し方: 2 を 1 にします。
パターン3
1 class Program { 2 static void Main(string[] args) { 3 int min = int.MinValue; 4 int result = min - 1 ; ^ 5 System.Console.WriteLine(result); 6 } 7 }
出力: 2147483647
下限を下回る場合も同様に、例外を出さず上限側へ折り返します。checked演算子を使うと検出できます。
直し方: 1 を 0 にします。
よくある誤解
「範囲を超えたら止まってくれる」という期待は誤りです。C#は既定でuncheckedという文脈で動作するため、オーバーフローを検出したい場合はcheckedを明示する必要があります。
まとめ
整数のオーバーフローが例外にならない理由は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。