2014-03-24 77 views
2

什麼是檢測算術溢出(或下溢)最合適的方法並獲得溢出計數?檢查算術溢出並獲得溢出計數?

爲了便於理解,我將使用byte,但這與int或任何其他基本整數類型相同。現在想象我有價值240,並想要添加24。顯然是算術溢出。使用checked關鍵字這是很容易,至少檢測...

byte value = 240; 
try 
{ 
    checked 
    { 
     value += 24; 
    } 
} 
catch (OverflowException e) 
{ 
    // handle overflow, get overflow count via % etc. 
} 

...拋出一個異常。

這是我目前正在使用的。

但是,我不太喜歡這個例外處理。例外通常非常昂貴,我想從一開始就避免它們。對我來說,這似乎是一個Boneheaded-Exception無論如何。 有沒有一些算術魔術我可以做,以檢測這個前期?

回答

2

我想你可以檢查當前值和最大值,如果大到足以做加法的區別:

var difference = byte.MaxValue - value; 

if(difference >= 24)//OK to add 24 
else//will cause overflow 

要檢測下溢,則可以使用byte.MinValue值,而不是:

var difference = value - byte.MinValue; 
if(difference >= 24)//OK to subtract 24 
else//will cause underflow 

有了這些考慮,你可以去儘可能使他們的一些推廣方法:

public static class OverflowExtensions 
{ 
    public static bool WillAdditionOverflow(this byte b, int val) 
    { 
     return byte.MaxValue - b < val; 
    } 

    public static bool WillSubtractionUnderflow(this byte b, int val) 
    { 
     return b - byte.MinValue < val; 
    } 
} 

,您可以使用像這樣:

using MyApp.OverflowExtensions; 
//... 

if(value.WillAdditionOverflow(24)) 
    //value + 24 will cause overflow 

if(value.WillSubtractionUnderflow(24)) 
    //value - 24 will cause underflow 
1

這樣的事情呢?

if (byte.MaxValue - 240 < 24) 
{ 
    // handle overflow 
} 

下溢,說,看你能不能做的24 - 240

if (byte.MinValue + 240 > 24) 
{ 
    // handle underflow 
} 
+0

糾正我,如果我錯了,但這不檢測下溢,或者它? –

+0

對。你將不得不寫一個類似的下流檢查。 –

1

這樣做有什麼這個其他方式?

byte oldValue = 240; 
byte newValue; 

unchecked 
{ 
    newValue = (byte)((oldValue + 24) % 255); 
} 

// if (newValue < oldValue), overflow happened and newValue 
// contains the "amount" of overflow 

(該% 255有必要對字節,因爲byte + byte是一個整數,或許對於可移植性原因)

注意,這僅適用於如果您要添加的數量的大小的值(同即都是字節,都是整數...),它只適用於添加。對於減法,您只需反轉比較(newValue > oldValue)。倍增時沒有任何用處。

這種方法的優點在於,它不依賴於具有足夠大的數據類型而不會導致溢出,這是其他一些方法的弱點。