2010-01-13 83 views
49

我在Project Euler(順便說一下,很棒的網站)有問題10的奇怪經歷。這項任務是計算所有低於200萬的素數的總和。在C#中int沒有溢出異常?

我用一個int作爲總和,我的算法產生了一個答案,但是當我粘貼它來驗證答案時,這是錯誤的。

事實證明,結果太大,不適合int,但不會導致溢出錯誤或什麼?相反,它只是返回一個遠離真實答案的值。

當我將類型改爲long時,所有內容都是hunky dory。

+5

你真的希望每一個整數運算檢查溢出? – 2010-01-13 12:11:55

+4

好吧,在這種特殊情況下,它會節省我一些時間;) – erikric 2010-01-13 12:18:51

+1

在這種情況下,是的。儘管絕大多數操作不可能溢出。如果編譯器可以證明這一點並禁用檢查作爲結果,這將是有趣的,但我非常懷疑它的確如此。 – Thorarin 2010-01-13 12:34:08

回答

73

C#整數操作默認情況下不會在溢出時引發異常。你可以做到這一點通過項目設置,或通過使計算checked

int result = checked(largeInt + otherLargeInt); 

現在的操作將拋出。

與之相反的是unchecked,它使任何操作顯式取消選中。顯然,只有在項目設置中啓用了檢查操作時,這纔有意義。

+0

除非您處於調試模式,我認爲默認情況下會檢查int操作。 – Ant 2010-01-13 13:52:00

+5

沒有。發生這種情況時我運行在調試模式下。 – erikric 2010-01-13 14:21:57

+0

哦。我立場糾正。我確定我的Project Euler項目告訴我在調試模式下溢出。:/ – Ant 2010-01-14 10:02:26

19

在C#中不會拋出一個OverflowException(在VB中,每次默認拋出異常)。

爲了讓你有嵌入代碼在checked上下文中的錯誤時拋出:

byte value = 241; 
checked 
{ 
    try 
    { 
     sbyte newValue = (sbyte) value; 
     Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.", 
      value.GetType().Name, value, 
      newValue.GetType().Name, newValue); 
    } 
    catch (OverflowException) 
    { 
     Console.WriteLine("Exception: {0} > {1}.", value, SByte.MaxValue); 
    } 
}  

MSDN詳細介紹了:

對於算術,鑄造,或 轉換操作扔一個 OverflowException,操作必須 發生在已檢查的上下文中。通過 默認,算術運算和 溢出在Visual Basic中被檢查; C#中的 ,它們不是。如果操作 發生在未檢查的上下文中,則 結果將被截斷,方法是丟棄不適合目標類型的任何 高位。

6

我已經添加了CMT,但它也許有趣一些您:

msdn告訴我們:

的整數運算溢出或者 拋出一個OverflowException異常或 丟棄最 有效位

但是

十進制算術溢出總是 拋出一個OverflowException。

當整數溢出時,什麼 發生取決於執行 方面,它可以檢查或 選中。在選中的上下文中,會引發OverflowException。在 未經檢查的上下文中,結果的最重要的位 被丟棄並且繼續執行。因此,C#讓您選擇 處理或忽略溢出。

+0

這是有道理的,因爲小數主要用於貨幣或科學計算,並且您可能寧願讓它們拋出然後靜默失敗。 – Snellface 2016-03-28 11:13:24

6

默認情況下,C#不檢查整數上的算術溢出。您可以使用/checkedcompiler option或在Visual Studio中啓用「檢查算術上溢/下溢」(項目屬性 - 生成 - 高級)來更改此項。

您可以使用checked and unchecked keywords在個案基礎上覆蓋默認值。如果您依賴於在一段代碼中進行檢查,則使用checked明確啓用它是個不錯的主意。

int j = checked(i * 2); 

checked 
{ 
    int j = i * 2; 
    // Do more stuff 
} 

注意,浮點運算不會拋出一個OverflowException和小數運算始終拋出OverflowException。另見C# operators

9

這是因爲,默認情況下,C#不會爲整數溢出和下溢而拋出任何異常。有幾件事你可以在這裏做。

選項1

您必須啓用例外被拋出去 項目=>屬性=>生成標籤=>高級=>檢查算術溢出下溢。(請確保您打勾的選項)

enter image description here

確保你打勾的選項

選項2

使用選中的塊並引發溢出異常來處理這種情況。示例代碼片斷將

 try 
     { 
      checked 
      { 
       int y = 1000000000; 
       short x = (short)y; 
      } 
     } 
     catch (OverflowException ex) 
     { 
      MessageBox.Show("Overflow"); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error"); 
     } 

希望這將幫助你... :)

+2

選項1是許多人不知道的癥結所在。你得到我的+1。 – RBT 2016-04-29 23:53:49