這個練習展示了各種數值型別在溢位時的行為,也就是當它們的容量不足以容納某個運算(例如算術運算或轉型)所產生的值時會發生什麼事。
byte、ushort、uint、ulong)會繞回零(該型別的最大值加 1 會扮演模數的角色),除非廣義來說它們出現在 checked 區塊中,這種情況下會擲回 OverflowException 執行個體。int和long的行為類似,只是它們分別會繞回 int.MinValue 和 long.minValue。int one = 1;
checked
{
int expr = int.MaxValue + one; // overflow exception is thrown
}
// or
int expr2 = checked(int.MaxValue + one); // overflow exception is thrown
checked 狀態只適用於區塊中直接出現的運算式。被呼叫的函式中的溢位狀態並不會被攔截。float 與 double型別會進入 無限大 狀態,可以透過 float.IsInfinity() 等方式來測試。double d = double.MaxValue;
d *= 2d;
Double.IsFinite(d)
// => false
decimal 型別的數字會導致擲回 OverflowException 執行個體。unchecked 關鍵字,適用於你想在 checked 區塊內反轉 unchecked 效果的場合,或是已使用編譯器設定的時候。沒有擲回例外就發生的溢位可能會造成問題,因為一般來說,錯誤狀況越早被回報越好。
int和float的溢位問題,可以透過把結果指定給long、decimal或double型別的變數來緩解。
如果大整數對你的程式碼來說不可或缺,那麼使用BigInteger型別是一個選項。
當然,有些情況下讓整數繞回是合理的,特別是在無號值的情況。經典的例子是雜湊碼,它把整數的寬度當成一種模數來使用。
你通常會發現在程式碼庫中,當uint或ulong被當作識別碼使用時,往往不會做檢查,因為大家認為這得不償失。這也適用於從領域本身就能明顯看出不會涉及極大值的情況。不過,看看這個當作前車之鑑吧。