相等运算符 returns 不等值时为真

Equality operator returns true for unequal values

我有两个 doublelong 类型的变量 y 和 z 。我的问题是相等运算符 returns 对它们来说是真的,即使它们具有不相等的值,正如您在下面的代码片段中看到的那样。

public class Test {
    public static void main(String[] args) throws Exception {
        double y = (double) Long.MAX_VALUE;
        System.out.println(y);//9.223372036854776E18
        long z = Long.MAX_VALUE - 1;
        System.out.println(z);//9223372036854775806
        System.out.println(y == z);//=============true
    }
}

我的问题是如果 z 的值比 y 小,为什么 y==z 会变为真

谁能解释一下这种行为。

这里发生了两件事。

  1. double == long中,longpromoteddouble。表达式 y == z 的计算结果与 (double) Long.MAX_VALUE == (double) (Long.MAX_VALUE - 1) 相同。

  2. double 只有 53 位精度。当将 long > 253 转换为 double 时,最低有效位将被四舍五入,使得 (double) Long.MAX_VALUE (= 263 - 1) 和(double) (Long.MAX_VALUE - 1)成为相同的值。

要评估 y == z,Java 必须将 z 提升为双倍。

任何大于 2^53 - 1 的 long 值都不能精确地用双精度表示。

(double) Long.MAX_VALUE 等于 (double) (Long.MAX_VALUE - 1),因为 double 没有足够的精度来清楚地表示两个值。

您可以使用 Math.nextDown:

查看获得不同浮点值所需的增量(如 Long.MAX_VALUE - delta
double delta = y - Math.nextDown(y);

这会产生 1024。