使用中間變量交換兩個int型變量的值:
int a = 29; int b = 10; a = a+b; b = a-b; a = a-b;
相信大家很容易寫出來,但考慮到邊界值情況時會有一些有趣的事情。
我們知道有一個int.MaxValue和int.MinValue表示int型的最大值和最小值。
當我們直接定義:int a = int.MaxValue + 1的時候,編譯器會提示出錯:
在申明x變量時程序編譯會報錯。
但下面申明的變量a,b進行相加時可以肯定的是出現了算術溢出錯誤,但卻依然可以得到正確的結果。
在執行完a = a+b后發現a的值變成了-3
而后面兩步計算均能得出正確的結果….
解釋:參考msdn操作符說明: https://msdn.microsoft.com/zh-cn/library/6a71f45d
操作符重載和隱式轉換: https://msdn.microsoft.com/zh-cn/library/s53ehcz3
算術溢出
算術運算符(+、-、*、/)的計算結果可能會超出所涉數值類型的可取值范圍。 詳細信息應參考特定運算符的相關章節,而一般情況下:
- 整數算術溢出或者引發 OverflowException,或者放棄結果的最高有效位。 整數被零除總是引發 @System.DivideByZeroException。
發生整數溢出時,具體影響視執行上下文而定,上下文可為 checked 或 unchecked。 在 checked 上下文中引發 OverflowException。 在 unchecked 上下文中,放棄結果的最高有效位並繼續執行。 因此,C# 讓你有機會選擇處理或忽略溢出。 默認情況下,算術運算發生在 unchecked 上下文中。
除算術運算以外,整型類型之間的顯式轉換也會導致溢出(例如,將 long 顯式轉換成 int),並受到 checked 或 unchecked 執行的約束。 但是,位運算符和移位運算符永遠不會導致溢出。
- 浮點算術溢出或被零除從不引發異常,因為浮點類型基於 IEEE 754,因此可以表示無窮大和 NaN(非數值)。
- 小數算術溢出總是引發 OverflowException。 小數被零除總是引發 DivideByZeroException。
總結:大多數情況下數值計算很少有機會碰到溢出,但具體特殊場景應具體對待。
如:
1, 變量初始化時給定為int.MaxValue,在使用時一定要考慮計算溢出。
2, 在大量的循環或遞歸中計算時有可能會導致算術溢出。
3, 從IO輸入設備中取值,尤其是用戶輸入的值中很有可能是一個溢出的無效輸入。
4, 注意.NET CLR默認情況下算術運行是發生在unchecked上下文。如果發生算術溢出,程序不會出錯,可能得到正確或錯誤的結果。