【发布时间】:2013-04-11 12:52:30
【问题描述】:
使用C#,我有一些自定义类,我需要能够检测整数溢出并返回默认最小值或最大值,具体取决于溢出是由于结果超过最大值还是低于最大值最小值。我似乎找不到关于如何检测任何地方发生的溢出“类型”的建议。
这些类分为两种一般类型:使用有符号值的类和使用无符号值的类。
例如,这里是处理 Int32 值的类之一:
public class Stat32Tf : IStat32T<float>
{
#region fields
private int baseValue, baseAdjustment;
private float baseMultiplier;
#endregion
#region ctors
public Stat32Tf()
{
baseValue = 0;
baseAdjustment = 0;
baseMultiplier = 1f;
}
public Stat32Tf(int baseValue, int baseAdjustment = 0, float baseMultiplier = 1f)
{
this.baseValue = baseValue;
this.baseAdjustment = baseAdjustment;
this.baseMultiplier = baseMultiplier;
}
#endregion
#region properties
public int BaseValue
{
get
{
return baseValue;
}
set
{
baseValue = value;
}
}
public int BaseAdjustment
{
get
{
return baseAdjustment;
}
set
{
baseAdjustment = value;
}
}
public float BaseMultiplier
{
get
{
return BaseMultiplier;
}
set
{
baseMultiplier = value;
}
}
public int TruncValue
{
get
{
return (int)Value;
}
}
public float Value
{
get
{
return (baseValue + baseAdjustment) * baseMultiplier;
}
}
#endregion
}
如您所见,该类的思想是保存一个基值、一个调整值和一个乘数值,并在 Value 属性中返回聚合值。 (正如它所暗示的,TruncValue 属性只是返回截断的整数值,删除任何小数值)。
目标是处理 Value 属性的“get”访问器中的溢出,如果结果超过最大 int 值,则返回 int.MaxValue,如果低于最小值,则返回 int.MinValue,所有没有抛出实际的溢出错误。让我感到棘手的部分是调整值和乘数也可能是负值(根据设计要求)。
实现此目的的安全方法是什么?我还没有找到任何资源来解决这种情况。我猜需要使用某种算术算法来确定结果是否超过或低于。
【问题讨论】:
-
如果有溢出并且结果是肯定的,那么溢出就会发生。如果结果为负,则溢出结束
-
@caerolus 涉及乘法,这并不容易,结果仍然可以具有预期的符号:
123456*987654 = 1672727936用于具有环绕溢出行为的 32 位(如果有符号则为二进制补码)整数。 -
仅供参考,默认情况下,C# 中的整数溢出不会引发 OverflowException;仅在
checked环境中。 -
@DanielFischer 你说的很对,我指的只是添加。也许将整个事情计算为
double,检查溢出然后再转换回float? -
@John Willemse 是的,开发环境正在运行检查以进行调试,但为此它是微不足道的,因为我们实际上并不希望抛出溢出异常。我们只需要能够确定结果是否“会”溢出,然后确定溢出的方向,以便可以返回适当的默认值。
标签: c# .net overflowexception