为什么(int)double.NaN和(int)double.PositiveInfinity是0?
在C#中 ,如果你是0/0
你会得到一个例外。
但是如果你0.0/0
或0.0/0.0
分别得到double.NaN
和double.Infinity
。
但如果将这些结果转换为int
,则得0。
> (int)double.PositiveInfinity 0 > (int)double.NaN 0
为什么会这样? 是不是运行时应该给出转换错误,因为无穷大显然不是零?
这取决于您所处的上下文类型。如果您使用已checked
上下文,您将获得exception。 规范的相关部分是第6.2.1节:
对于从float或double到整数类型的转换,处理取决于转换发生的溢出检查上下文(第7.6.12节):
- 在已检查的上下文中,转换过程如下:
- 如果操作数的值为NaN或无穷大,则抛出System.OverflowException。
- 否则,源操作数向零舍入为最接近的整数值。 如果此整数值在目标类型的范围内,则此值是转换的结果。
- 否则,抛出System.OverflowException。
- 在未经检查的上下文中,转换始终成功,并按如下方式继续。
- 如果操作数的值为NaN或无限,则转换的结果是目标类型的未指定值。
- 否则,源操作数向零舍入为最接近的整数值。 如果此整数值在目标类型的范围内,则此值是转换的结果。
- 否则,转换的结果是目标类型的未指定值。
所以在未经检查的上下文中,答案不一定是0 – 这是一个未指定的int
值。 实际上,在我的测试中,它在未经检查的上下文中显示为int.MinValue
而不是0。
但从根本上说,如果要进行检查,请使用已检查的上下文(至少对于该表达式)。
这主要是因为double.NAN和double.PositiveInfity(或double.Negative)不是数字而是识别概念的值。
当操作结果未定义时,方法或运算符返回NaN。 例如,将零除零的结果是NaN,如以下示例所示。
试试这个来说明这个概念。
if ((0 / zero) == Double.NaN) Console.WriteLine("0 / 0 can be tested with Double.NaN."); else Console.WriteLine("0 / 0 cannot be tested with Double.NaN; use Double.IsNan() instead.");