判断运算是否会溢出?

Determine if operation will result in overflow?

我的应用程序中有一些 class 表示物理单位的元素,例如温度。这些 classes 可以让一些单位与之相关联并进行更改,例如摄氏度和开尔文。它们还有用户定义的最大值和最小值。

当我想更改单位时,我会得到两个给定单位之间的转换因子,然后更改 class 中的 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 之间是否存在某个阈值,因为在那么大的值下精度如此之低?

如果变量是双精度变量,您应该检查 Infinity

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

bool overflowed = double.IsInfinity(Min);

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


如果变量是一个整数,你可以将语句包装在一个checked块中,这将在操作溢出时引发异常。这不是预防措施,但可以起到作用。

checked
{
   ...
}

你可以try...catch那个。

浮点运算不会抛出异常。

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

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.IsPositiveInfinity(d)double.IsNegativeInfinity() 为真,则 double.IsInfinity(d) 为真。

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