除零异常奇怪现象

4
今天我遇到了一个问题,当我不小心除以零时,却没有抛出异常。当我使用调试器查看时,调试器中显示的是“NaN”。当我尝试使用NUnit重新创建此场景时,“Assert”说我正在返回“Infinity”。无法完全让调试器显示“NaN”,但我想知道为什么在这种情况下没有抛出错误?我花了相当长的时间来跟踪这个问题,而我本应该认为会抛出一个异常?
以下是测试代码:
public class DivideByZero {

    private int TotalQaOneToFour;
    private int TotalGrade = 10;

    public DivideByZero(int TotalQaOneToFour) {
      this.TotalQaOneToFour = TotalQaOneToFour;
    }

    public Double QualityReportAverageRounded {
      get {
        return Math.Round((double)TotalGrade / TotalQaOneToFour, 2);
      }
    }
  }


  [TestFixture]
  public class DivideByZeroTest {

    [Test]
    public void TestThatDivideByZeroThrowsWhenUsingMathRound() {

      var dbz = new DivideByZero(0);

      Assert.AreEqual(0, dbz.QualityReportAverageRounded);
    }

  }

以下是 NUnit 的输出:

测试 'DivideByZeroTest.TestThatDivideByZeroThrowsWhenUsingMathRound' 失败:
预期结果:0
实际结果:无穷大
在 DivideByZero.cs(33,0):
DivideByZeroTest.TestThatDivideByZeroThrowsWhenUsingMathRound()

共有 1 个测试失败,0 个测试通过,0 个测试跳过,总计用时 0.41 秒 (NUnit 2.6.1)。


不同值类型之间除以零行为的不一致性 - pixelbadger
你可以始终创建一个覆盖方法,如果除数为0,则抛出异常。 - Sayse
2个回答

12

调试器无法显示NaN,但我想知道为什么在这种情况下没有抛出错误?

因为那会违反规范 :) 基本上,在此处不需要抛出异常,因为IEEE-754 a) 定义了如何处理除以0; b) 对于除以0的结果有适当的值。这对于整数类型(和decimal)来说是不成立的,这也是你会得到DivideByZeroException的地方。

如果您将任何非零、非NaN值除以零,应该会得到无穷大(正或负)。如果你将零(或NaN)除以零,你应该得到NaN。

样例代码:

using System;

class Test
{
    static void Main()
    {
        // Prevent everything being computed at compile-time
        double zero = 0d;
        Console.WriteLine(1d / zero);  // Infinity
        Console.WriteLine(0d / zero);  // NaN
        Console.WriteLine(-1d / zero); // -Infinity
    }
}

来自于C# 5规范第7.8.2节(其他版本可能适用不同编号):

整数除法

[...]
如果右操作数的值为0,则会抛出 System.DivideByZeroException 异常。
[...]

浮点数除法

商根据IEEE 754算术规则计算。以下表格列出了所有可能的非零有限值、零、无穷大和NaN的组合的结果。

(接下来是一张给出与之前描述相同类型的结果的表格。)


+1 - C# 规范 - 7.7.2 除法运算符 - Alexei Levenkov
@AlexeiLevenkov:我正准备获取规范 :) 将引用它。 - Jon Skeet
过于苛求的挑剔:非零值除以零也可能返回NaN - 如果被除数本来就是1的话 ;) - Daniel Fischer

1
在浮点数中,如果除以零,就会得到无穷大或非数字(NaN)。在整数中除以零会导致异常。
当您将非零值除以零时,会产生无穷大。当您将零除以零时,会产生NaN。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接