【问题标题】:Why doesn't Java throw an Exception when dividing by 0.0?为什么Java除以0.0时不抛出异常?
【发布时间】:2011-01-23 19:18:02
【问题描述】:

我有代码来计算两个数字之间的百分比差异 - (oldNum - newNum) / oldNum * 100; - 其中两个数字都是 doubles。我希望在 oldNum 为 0 的情况下必须添加某种检查/异常处理。但是,当我对 oldNum 和 newNum 的值都为 0.0 进行测试运行时,执行继续进行,就好像什么都没发生并且没有引发错误一样。使用ints 运行此代码肯定会导致算术除零异常。为什么 Java 会忽略 doubles?

【问题讨论】:

标签: java types integer double divide-by-zero


【解决方案1】:

Java 的 floatdouble 类型与几乎所有其他语言(以及几乎所有硬件 FP 单元)一样,实现了浮点数学的 IEEE 754 标准,该标准要求除以零以返回特殊的“无穷大”值。抛出异常实际上会违反该标准。

整数运算(由 Java 和大多数其他语言和硬件实现为 two's complement 表示)是不同的,没有特殊的无穷大或 NaN 值,因此抛出异常是一种有用的行为。

【讨论】:

  • 这个问题的正确答案应该是这个。我需要知道为什么floatdouble 不会导致异常。谢谢。
  • 这应该是标记的正确答案。当前标记为正确的答案没有回答问题,也没有明确表明 Java 遵循 IEEE 754。
【解决方案2】:

除以零的结果在数学上是undefined,可以用浮点数/双精度表示(如NaN - 不是数字),但它不是,从根本上说是错误的。

由于整数必须包含特定的数值,因此在处理它们时必须在除以零时引发错误。

【讨论】:

  • 没错。这是在 Java 语言规范中定义的:java.sun.com/docs/books/jls/third_edition/html/…
  • 我认为应该有一个 Integer.NaN
  • @trinithis:您的解释与没有 Integer.NaN 的原因无关。原因很简单,浮点算术的 IEEE 标准规定了这样的特殊值,而整数算术的准标准(二进制补码)没有这样的特殊值,因此将如何处理被零除(引发中断)留给实现者或异常,指定一个特殊值,或者只是不定义结果)。
  • @Kris:严格来说它不可能是无穷大,因为 lim(1/x) 与 x -> 0+ 和 x -> 0- 不同。但这是一个小问题。
  • x/0 不是无穷大,结果未定义。当 y 趋于 0 时,x/y 趋于无穷大。抱歉线程坏死。
【解决方案3】:

除以零(0 或 0.00)

  1. 如果你将 double 除以 0,JVM 将显示 Infinity

    public static void main(String [] args){ double a=10.00; System.out.println(a/0); }

    控制台: Infinity

  2. 如果将 int 除以 0,则 JVM 将抛出 算术异常

    public static void main(String [] args){ int a=10; System.out.println(a/0); }

    控制台:Exception in thread "main" java.lang.ArithmeticException: / by zero

  3. 但是如果我们将 int 除以 0.0,那么 JVM 将显示 Infinity:

    public static void main(String [] args){ int a=10; System.out.println(a/0.0); }

    控制台:Infinity

这是因为 JVM 会自动将类型强制转换为 double,所以我们得到的是 infinity 而不是 ArithmeticException。

【讨论】:

    【解决方案4】:

    double 的存储方式与 int 完全不同。有关 Java 如何处理双重计算的更详细说明,请参阅http://firstclassthoughts.co.uk/java/traps/java_double_traps.html。您还应该阅读浮点数,特别是 Not a Number (NaN) 的概念。

    如果您有兴趣了解有关浮点表示的更多信息,我建议您阅读this document(Word 格式,抱歉)。它深入研究了数字的二进制表示,这可能有助于您的理解。

    【讨论】:

      【解决方案5】:

      虽然 Java 开发人员知道 double 基本类型和 Double 类,但在进行浮点运算时,他们并没有足够注意 Double.INFINITYNaN-0.0 和其他控制算术计算的规则涉及他们。

      这个问题的简单答案是它不会抛出ArithmeticException 并返回Double.INFINITY。另外,请注意,比较 x == Double.NaN 始终评估为 false,即使 x 本身是 NaN

      要测试x 是否为NaN,应使用方法调用Double.isNaN(x) 来检查给定数字是否为NaN。这与SQL 中的NULL 非常接近。

      它可能对你有帮助。

      【讨论】:

        猜你喜欢
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多