为什么(int)double.NaN和(int)double.PositiveInfinity是0?

时间:2013-01-09 19:11:50

标签: c#

C#中,如果您0/0出现例外情况。

但如果您0.0/00.0/0.0分别获得double.NaNdouble.Infinity

但如果您将这些结果投放到int,则会得到0。

> (int)double.PositiveInfinity
0
> (int)double.NaN
0

为什么会这样?是不是运行时应该给出转换错误,因为无穷大显然不是零?

2 个答案:

答案 0 :(得分:15)

这取决于您所处的上下文类型。如果您使用checked上下文,您将获得例外。规范的相关部分是第6.2.1节:

  

对于从float或double到整数类型的转换,处理取决于转换发生的溢出检查上下文(第7.6.12节):

     
      
  • 在已检查的上下文中,转换过程如下:   
        
    • 如果操作数的值为NaN或无限,则抛出System.OverflowException。
    •   
    • 否则,源操作数向零舍入为最接近的整数值。如果此整数值在目标类型的范围内,则此值是转换的结果。
    •   
    • 否则,抛出System.OverflowException。
    •   
  •   
  • 在未选中的上下文中,转换始终成功,并按如下方式进行。   
        
    • 如果操作数的值为NaN或无穷大,则转换结果为目标类型的未指定值。
    •   
    • 否则,源操作数向零舍入为最接近的整数值。如果此整数值在目标类型的范围内,则此值是转换的结果。
    •   
    • 否则,转换结果是目标类型的未指定值。
    •   
  •   

因此,在未经检查的上下文中,答案不是必然为0 - 它是未指定的int值。实际上,在我的测试中,它在未经检查的上下文中显示为int.MinValue而不是0。

但从根本上说,如果你想做检查,请使用选中的上下文(至少对于那个表达式)。

答案 1 :(得分: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.");