Java除法运算异常

Java divide operation exception

给定以下代码:

  long testNum = 1000;
  double midNum = testNum/60000;
  System.out.println(midNum);
  long another = Math.round(7600/midNum);
  System.out.println(another);

输出为:

0.0
9223372036854775807
  1. 为什么第一个输出是0.0?我怎样才能在 java 中得到正确的结果?
  2. 既然第一个输出是0,为什么下一个表达式有结果呢?它不应该抛出一个 by zero 表达式吗?

Why the first output is 0.0?

您使用的是整数除法,所以这是正确的结果。

How could I get the right result in java?

不要使用整数除法,而是使用浮点数,这是使其中一个值成为浮点数的最简单方法。

double midNum = testNum/60000.0;

double midNum = testNum/60e3;

Since the first output is 0, why the next expression has an result?

浮点运算使用 IEEE-754 标准(有时称为 IEEE-753.99999999999998 ;) 在浮点数中,你永远不会在 Java 中得到异常,你可能会得到无穷大、负无穷大或 NaN。

整数没有 Infinity 或 NaN 并且无法表示它,因此它产生了一个异常。

当您将任何数字四舍五入到 long 时,它会为您提供最接近的可表示值,即 Long.MAX_VALUE

顺便说一句

long l = Math.round(Double.POSITIVE_INFINITY); // l == Long.MAX_VALUE
long l = Math.round(Double.NEGATIVE_INFINITY); // l == Long.MIN_VALUE
long l = (long) Double.NaN; // l == 0

来自 Double 你可能会觉得这很有趣。

public final class Double extends Number implements Comparable<Double> {
    /**
     * A constant holding the positive infinity of type
     * {@code double}. It is equal to the value returned by
     * {@code Double.longBitsToDouble(0x7ff0000000000000L)}.
     */
    public static final double POSITIVE_INFINITY = 1.0 / 0.0;

    /**
     * A constant holding the negative infinity of type
     * {@code double}. It is equal to the value returned by
     * {@code Double.longBitsToDouble(0xfff0000000000000L)}.
     */
    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

    /**
     * A constant holding a Not-a-Number (NaN) value of type
     * {@code double}. It is equivalent to the value returned by
     * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
     */
    public static final double NaN = 0.0d / 0.0;

    /**
     * A constant holding the largest positive finite value of type
     * {@code double},
     * (2-2<sup>-52</sup>)&middot;2<sup>1023</sup>.  It is equal to
     * the hexadecimal floating-point literal
     * {@code 0x1.fffffffffffffP+1023} and also equal to
     * {@code Double.longBitsToDouble(0x7fefffffffffffffL)}.
     */
    public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308

long 不能容纳小数。 Long 等于 int 只是具有更高的范围。

您应该使用小数或浮点数。

您的第一个结果是 0.0 的原因是您使用了隐式转换。当一个 long 除以一个数时,Java 假定该数是同一类型并且将进行 "long" 除法,没有余数。由于 1000/60000 介于 0 和 1 之间,因此结果有效地降为 0,当它是双精度值时转换为 0.0。您可以通过将一行更改为 double midNum = testNum/60000D;

来解决此问题

注意末尾的"D",表示60000是双数。这将强制将 long 转换为 double 并给出正确的结果。

对于第二部分,您基本上除以一个非常非常小的数字,使其看起来非常大。 0.0 不能用 double 精确表示,所以你实际上是在除以略高于 0.0 的值,当你修复另一部分时它会被修复。

使用类型转换运算符。 double midNum = (double)testNum/60000;