【问题标题】:Why is number divided by zero infinity in Java?为什么Java中的数字除以零无穷大?
【发布时间】:2013-08-30 22:48:36
【问题描述】:

为什么要在Java下面的代码

System.out.println(new Integer(1)/ new Double(0));

打印“无限”而不是未定义。这不是数学上的错误吗?

【问题讨论】:

  • 浮点数在数学上是错误的。 :)
  • 这可以编译吗?未定义包装器上的运算符。
  • @braindead 趣闻:(a + b) + c != a + (b + c) 用于浮点。 :)
  • @arynaq 对我有用。
  • 你也可以选择一个足够大的a,比如(a + 1) == a。这甚至没有进入NaNs。

标签: java floating-point double divide-by-zero


【解决方案1】:

这与浮点上的IEEE 754 standard 一致,Java 遵循。

【讨论】:

    【解决方案2】:

    在数学中,有许多不同的结构支持算术。最突出的数,例如自然数、整数和实数,不包括无穷大。在这些系统中,不支持除以零。

    其他系统确实包括至少一个无穷大。例如,参见real projective line。它确实允许除以零。

    只有一种方法可以了解特定系统中的数学定义或未定义 - 研究该系统。

    同样,操作是否可交换(a op b == b op a)和/或关联(a op (b op c) == (a op b) op c)取决于系统和操作。

    IEEE 754 二进制浮点是一个具有有限元素集的系统,包括两个无穷大。加法和乘法都是可交换的,但不是结合的。 Java real 和 double 算术都是基于它的。 Java 语言规范是确定 Java 浮点运算中定义或未定义的唯一方法。

    使用浮点数的许多最严重错误的基础是假设浮点数是实数,而不是有效但不同的系统。

    【讨论】:

      【解决方案3】:

      不,您不能在数学中除以零,但在 Java 中,Infinitynew Integer(1)/ new Double(0) 是正确的。 new Integer(0)/ new Double(0) 将是未定义的 (NaN)。

      Java 遵循 IEEE 标准,因此对于此类浮点运算,Infinity 是正确的。如果是1/0,就会出现ArithmeticException,因为在整数除法中,不允许被零除;没有int 表示无穷大。

      具体来说,在JLS, Section 15.17.2:

      [I]如果整数除法的除数为0,则 抛出 ArithmeticException。

      浮点除法的结果由以下规则确定 IEEE 754 算法:

      零除以零的结果为 NaN 非零有限值除以零会产生有符号无穷大。

      【讨论】:

      • 1/0 等于无穷大在数学上是不正确的。在算术方面,您不能除以零,而且数学不会区分实数和有理数。
      • 直觉的一种方法是浮点数是近似值。所以1.0 / 0.0可以被认为是“一个非常接近1的数字,除以一个非常接近0的数字”。结果是“一个非常大的数字”,近似为Infinity。这一切都是非常空洞和不精确的,但它得到了直觉。请注意,1 / Double.MIN_VALUE 也是 InfinityDouble.MIN_VALUEDouble 可以表示的最小正数。)
      • @Rapptz 是的,你是对的,我想我输入得太快了。已更正。
      • @yshavit 这是一个非常危险的直觉,因为理解 IEEE 754 浮点的其他方面的关键是浮点数不是“近似值”,它们准确地表示特定值.这是一个足够重要的概念,以至于这位浮点专家在向非专家密集型用户解释时,费心将您的误解列为“常见误解 (2)”,而事实是“FP 数仅代表其自身(理性)”的浮点数。 lipforge.ens-lyon.fr/www/crlibm/documents/cern.pdf
      • / 视为“近似除法”通常比将double 值视为实数的近似值更好。
      【解决方案4】:

      简而言之:浮点数可以表示无穷大(甚至可以表示产生非数字值的运算),因此产生这种结果的运算(例如除以 0)是有效的。

      【讨论】:

        【解决方案5】:

        当今浮点标准设计中的一个更好的设计决策是允许除以零之类的东西产生一个特殊的标记值,该值表明某些东西超出了范围,而不是使程序崩溃。然后,使用结果的代码可以决定这种标记值在多大程度上表示主要问题或次要问题。例如,绘制函数的程序可能会在绘制其余部分时简单地忽略无法计算值的点。

        很少将浮点数作为其真值输出。相反,它将输出为足以识别其值的一些字符串。将非零数除以零时生成的标记值打印为“无穷大”,但这并不意味着它在数学上是无穷大。相反,这意味着它是用于表示一个结果的哨兵值,该结果与任何其他大于大约 2^1024 的数字都无法区分,并且应该比任何其他定义的结果排名更高。对于一个与小于 -(2^1024) 的任何其他数字无法区分的结果存在另一个标记值,并且其排名应该小于任何其他定义的结果。第三种存在于无法计算但不符合任一类别的结果。

        对超过 2^1024 的计算和正数除以零使用相同标记的原因是,当将一个非常大的正数除以一个非常小的正数时,两种情况都会出现。如果这种比较的结果是“正无穷大”,则排序高于一切,即使除以最小的最小正数时,除以该数字的“一半”(四舍五入为零)时,它也应该保持不变。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-16
          • 1970-01-01
          相关资源
          最近更新 更多