确定操作是否会导致溢出?
我的应用程序中有一些代表物理单位的类,例如温度。 这些类能够使一些单元与它们相关联并进行更改,例如Celcius和Kelvin。 它们还具有用户定义的最大值和最小值。
当我想要改变单位时,我得到两个给定单位之间的转换因子,然后通过用转换因子执行一些算术运算来改变类中的Min
, Max
和Data
值。
Double ConversionFactor = GetConversionFactor(curUnits, newUnits); Units = newUnits; Min *= ConversionFactor; Max *= ConversionFactor; Data *= ConversionFactor;
我遇到的问题是,有时用户可能允许max和min值为某些类型的MinValue
和MaxValue
,例如Double
。 如果用户要更改转换因子大于1的单位,则会导致溢出。
在C#中是否有办法检测溢出和下溢是否会发生这种溢出?
从我可以告诉我的一些测试,我认为我只需要检查操作的结果是否不等于正或负无穷大? 如果是这样,我可以将值设置回MinValue
或MaxValue
。
另外,奖金问题。 在我的测试中,我发现如果我创建一个Double max = Double.MaxValue
并添加一些小到100的东西。 该值不会改变。
为什么是这样? MaxValue
和PositiveInfinity
之间是否有一些阈值,因为精度MaxValue
而且值很大?
如果变量是double,则应检查Infinity
。
最好的方法是使用double.IsInfinity
,它将检查下溢和溢出(正无穷大)。
bool overflowed = double.IsInfinity(Min);
如果您愿意,可以将其包装在自己的扩展方法中。
如果变量是整数,则可以将语句包装在已checked
块中,这会在操作溢出时导致exception。 这不是预防性的,但它确实起到了作用。
checked { ... }
你可以try...catch
那个。
浮点运算不会抛出exception。
相反,您必须执行操作,然后检查结果,例如:
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()
为true,则double.IsInfinity(d)
将为true。
正如您所观察到的,为double.MaxValue
添加一个相对较小的数字不会导致double.Infinity
。 这是因为舍入 – 您添加的值小于可以为指数如此大的双精度表示的值。