C# 检查算术溢出并获取溢出计数?
检测算术溢出(或下溢)并获取溢出计数的最合适方法是什么 为了便于理解,我将使用C# 检查算术溢出并获取溢出计数?,c#,exception,math,integer-overflow,integer-arithmetic,C#,Exception,Math,Integer Overflow,Integer Arithmetic,检测算术溢出(或下溢)并获取溢出计数的最合适方法是什么 为了便于理解,我将使用byte,但int或任何其他基本整数类型也是如此。现在想象一下,我有240的值,并想加上24。显然是算术溢出。使用checked关键字,这至少很容易检测到 byte value = 240; try { checked { value += 24; } } catch (OverflowException e) { // handle overflow, get over
byte
,但int
或任何其他基本整数类型也是如此。现在想象一下,我有240的值,并想加上24。显然是算术溢出。使用checked
关键字,这至少很容易检测到
byte value = 240;
try
{
checked
{
value += 24;
}
}
catch (OverflowException e)
{
// handle overflow, get overflow count via % etc.
}
。。。通过抛出异常
这就是我目前正在使用的
但是,我不太喜欢这一个中的异常处理。例外情况通常非常昂贵,我希望从一开始就避免它们。对我来说,这似乎是一个好消息我可以做一些算术运算来预先检测这个问题吗?像这样的事情怎么样
if (byte.MaxValue - 240 < 24)
{
// handle overflow
}
我想您可以检查当前值和最大值之间的差值是否足够大,以便进行加法:
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;
}
}
换个方向做怎么样
byte oldValue = 240;
byte newValue;
unchecked
{
newValue = (byte)((oldValue + 24) % 255);
}
// if (newValue < oldValue), overflow happened and newValue
// contains the "amount" of overflow
字节oldValue=240;
字节新值;
未经检查
{
新值=(字节)((旧值+24)%255);
}
//如果(newValue
(字节上需要%255
,因为byte+byte
是一个整数,可能是出于可移植性的原因)
请注意,只有当您要添加的数字与值大小相同(即,两者都是字节,都是整数…)且仅适用于添加时,此选项才有效。对于减法,只需反转比较(newValue>oldValue
)。它在乘法时没有任何用处
这种方法的优点是它不依赖于数据类型足够大而不会首先导致溢出,这是建议的其他一些方法的一个缺点。如果我错了,请纠正我,但这不会检测到下溢,或者是吗?对。您必须为下溢编写类似的检查。
using MyApp.OverflowExtensions;
//...
if(value.WillAdditionOverflow(24))
//value + 24 will cause overflow
if(value.WillSubtractionUnderflow(24))
//value - 24 will cause underflow
byte oldValue = 240;
byte newValue;
unchecked
{
newValue = (byte)((oldValue + 24) % 255);
}
// if (newValue < oldValue), overflow happened and newValue
// contains the "amount" of overflow