确定操作是否会导致溢出?

时间:2015-11-17 15:38:35

标签: c# floating-point overflow

我的应用程序中有一些代表物理单位的类,例如温度。这些类能够让一些单元与它们相关联并进行更改,例如Celcius和Kelvin。它们还具有用户定义的最大值和最小值。

当我想要更改单位时,我得到两个给定单位之间的转换因子,然后通过执行某些算术运算来更改类中的MinMaxData值与转换因子。

Double ConversionFactor = GetConversionFactor(curUnits, newUnits);
Units = newUnits;
Min *= ConversionFactor;
Max *= ConversionFactor;
Data *= ConversionFactor;

我遇到的问题是,有时用户可能会允许最大值和最小值为某种类型的MinValueMaxValue,例如Double。如果用户要更改转换因子大于1的单位,则会导致溢出。

C#中是否有办法检测溢出和下溢是否会发生这种溢出?

从我可以告诉我的一些测试,我认为我只需要检查操作的结果是不等于正无穷大?如果是这样,我可以将值设置回MinValueMaxValue

另外,奖金问题。在我的测试中,我发现如果我创建一个Double max = Double.MaxValue并添加一些小到100的东西。值不会改变。

为什么会这样? MaxValuePositiveInfinity之间是否存在某个阈值,因为精度太低而且值很大?

2 个答案:

答案 0 :(得分:5)

如果变量是double,则应检查Infinity

最好的方法是使用double.IsInfinity,它会检查下溢和溢出(正无穷大)。

bool overflowed = double.IsInfinity(Min);

如果您愿意,可以将其包装在自己的扩展方法中。

如果变量是整数,则可以将语句包装在checked块中,这会在操作溢出时导致异常。这不是预防性的,但它确实起到了作用。

checked
{
   ...
}

你可以try...catch那个。

答案 1 :(得分:1)

浮点运算不会抛出异常。

相反,您必须执行操作,然后检查结果,例如:

double d1 = double.MaxValue;
double d2 = double.MaxValue;
double d3 = d1*d2;

if (double.IsInfinity(d3))
    Console.WriteLine("Infinity");

if (double.IsPositiveInfinity(d3))
    Console.WriteLine("Positive Infinity");

d1 = double.MinValue;
d2 = double.MaxValue;
d3 = d1*d2;

if (double.IsInfinity(d3))
    Console.WriteLine("Infinity");

if (double.IsNegativeInfinity(d3))
    Console.WriteLine("Negative Infinity");

请注意,如果double.IsInfinity(d)double.IsPositiveInfinity(d)为真,则double.IsNegativeInfinity()为真。

如您所见,向double.MaxValue添加相对较小的数字不会导致double.Infinity。这是因为舍入 - 您添加的值小于可以为指数如此大的双精度值表示的值。