我在Project Euler(順便說一下,很棒的網站)有問題10的奇怪經歷。這項任務是計算所有低於200萬的素數的總和。在C#中int沒有溢出異常?
我用一個int作爲總和,我的算法產生了一個答案,但是當我粘貼它來驗證答案時,這是錯誤的。
事實證明,結果太大,不適合int,但不會導致溢出錯誤或什麼?相反,它只是返回一個遠離真實答案的值。
當我將類型改爲long時,所有內容都是hunky dory。
我在Project Euler(順便說一下,很棒的網站)有問題10的奇怪經歷。這項任務是計算所有低於200萬的素數的總和。在C#中int沒有溢出異常?
我用一個int作爲總和,我的算法產生了一個答案,但是當我粘貼它來驗證答案時,這是錯誤的。
事實證明,結果太大,不適合int,但不會導致溢出錯誤或什麼?相反,它只是返回一個遠離真實答案的值。
當我將類型改爲long時,所有內容都是hunky dory。
C#整數操作默認情況下不會在溢出時引發異常。你可以做到這一點通過項目設置,或通過使計算checked
:
int result = checked(largeInt + otherLargeInt);
現在的操作將拋出。
與之相反的是unchecked
,它使任何操作顯式取消選中。顯然,只有在項目設置中啓用了檢查操作時,這纔有意義。
在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#中的 ,它們不是。如果操作 發生在未檢查的上下文中,則 結果將被截斷,方法是丟棄不適合目標類型的任何 高位。
我已經添加了CMT,但它也許有趣一些您:
msdn告訴我們:
的整數運算溢出或者 拋出一個OverflowException異常或 丟棄最 有效位
但是
十進制算術溢出總是 拋出一個OverflowException。
也
當整數溢出時,什麼 發生取決於執行 方面,它可以檢查或 選中。在選中的上下文中,會引發OverflowException。在 未經檢查的上下文中,結果的最重要的位 被丟棄並且繼續執行。因此,C#讓您選擇 處理或忽略溢出。
這是有道理的,因爲小數主要用於貨幣或科學計算,並且您可能寧願讓它們拋出然後靜默失敗。 – Snellface 2016-03-28 11:13:24
默認情況下,C#不檢查整數上的算術溢出。您可以使用/checked
compiler 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。
這是因爲,默認情況下,C#不會爲整數溢出和下溢而拋出任何異常。有幾件事你可以在這裏做。
選項1
您必須啓用例外被拋出去 項目=>屬性=>生成標籤=>高級=>檢查算術溢出下溢。(請確保您打勾的選項)
確保你打勾的選項
選項2
使用選中的塊並引發溢出異常來處理這種情況。示例代碼片斷將
try
{
checked
{
int y = 1000000000;
short x = (short)y;
}
}
catch (OverflowException ex)
{
MessageBox.Show("Overflow");
}
catch (Exception ex)
{
MessageBox.Show("Error");
}
希望這將幫助你... :)
選項1是許多人不知道的癥結所在。你得到我的+1。 – RBT 2016-04-29 23:53:49
你真的希望每一個整數運算檢查溢出? – 2010-01-13 12:11:55
好吧,在這種特殊情況下,它會節省我一些時間;) – erikric 2010-01-13 12:18:51
在這種情況下,是的。儘管絕大多數操作不可能溢出。如果編譯器可以證明這一點並禁用檢查作爲結果,這將是有趣的,但我非常懷疑它的確如此。 – Thorarin 2010-01-13 12:34:08