2014-03-24 75 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)。倍增时没有任何用处。

这种方法的优点在于,它不依赖于具有足够大的数据类型而不会导致溢出,这是其他一些方法的弱点。