判断运算是否会溢出?
Determine if operation will result in overflow?
我的应用程序中有一些 class 表示物理单位的元素,例如温度。这些 classes 可以让一些单位与之相关联并进行更改,例如摄氏度和开尔文。它们还有用户定义的最大值和最小值。
当我想更改单位时,我会得到两个给定单位之间的转换因子,然后更改 class 中的 Min
、Max
和 Data
值] 通过使用转换因子执行一些算术运算。
Double ConversionFactor = GetConversionFactor(curUnits, newUnits);
Units = newUnits;
Min *= ConversionFactor;
Max *= ConversionFactor;
Data *= ConversionFactor;
我遇到的问题是,有时用户可能允许最大值和最小值是某些类型的 MinValue
和 MaxValue
,例如 Double
。如果用户要更改转换因子大于 1 的单位,这将导致溢出。
在 C# 中有没有一种方法可以检测上溢和下溢是否都会发生这种溢出?
根据我通过一些测试可以看出的情况,我认为我只需要检查运算结果是否不等于正无穷大或负无穷大?如果是这样,我可以将值设置回 MinValue
或 MaxValue
.
另外,加分问题。在我的测试中,我发现如果我创建一个 Double max = Double.MaxValue
并向其中添加一些像 100 这样的小值。该值不会改变。
这是为什么? MaxValue
和 PositiveInfinity
之间是否存在某个阈值,因为在那么大的值下精度如此之低?
如果变量是双精度变量,您应该检查 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
。这是因为四舍五入 - 您添加的值远小于指数如此之大的双精度值可以表示的值。
我的应用程序中有一些 class 表示物理单位的元素,例如温度。这些 classes 可以让一些单位与之相关联并进行更改,例如摄氏度和开尔文。它们还有用户定义的最大值和最小值。
当我想更改单位时,我会得到两个给定单位之间的转换因子,然后更改 class 中的 Min
、Max
和 Data
值] 通过使用转换因子执行一些算术运算。
Double ConversionFactor = GetConversionFactor(curUnits, newUnits);
Units = newUnits;
Min *= ConversionFactor;
Max *= ConversionFactor;
Data *= ConversionFactor;
我遇到的问题是,有时用户可能允许最大值和最小值是某些类型的 MinValue
和 MaxValue
,例如 Double
。如果用户要更改转换因子大于 1 的单位,这将导致溢出。
在 C# 中有没有一种方法可以检测上溢和下溢是否都会发生这种溢出?
根据我通过一些测试可以看出的情况,我认为我只需要检查运算结果是否不等于正无穷大或负无穷大?如果是这样,我可以将值设置回 MinValue
或 MaxValue
.
另外,加分问题。在我的测试中,我发现如果我创建一个 Double max = Double.MaxValue
并向其中添加一些像 100 这样的小值。该值不会改变。
这是为什么? MaxValue
和 PositiveInfinity
之间是否存在某个阈值,因为在那么大的值下精度如此之低?
如果变量是双精度变量,您应该检查 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
。这是因为四舍五入 - 您添加的值远小于指数如此之大的双精度值可以表示的值。