我有两个类型double
和long
的变量y和z。我的问题是等式运算符为它们返回true,即使它们具有不相等的值,如下面的代码片段所示。
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将成为现实。
有人可以解释这种行为。
答案 0 :(得分:4)
这里发生了两件事。
在double == long
中,long
为promoted到double
。表达式y == z
的评估方式与(double) Long.MAX_VALUE == (double) (Long.MAX_VALUE - 1)
相同。
double
只有53位精度。当转换长> 2 53 加倍,最低有效位将被舍入,使(double) Long.MAX_VALUE
(= 2 63 - 1)和(double) (Long.MAX_VALUE - 1)
变为相同值。
答案 1 :(得分:4)
要评估y == z
,Java必须将z
提升为双倍。
任何长于2^53 - 1
的长值都无法用双精确表示。
(double) Long.MAX_VALUE
等于(double) (Long.MAX_VALUE - 1)
,因为double没有足够的精度来清楚地表示这两个值。
您可以使用Long.MAX_VALUE - delta
查看所需的增量(如Math.nextDown
中所示)以获取不同的浮点值:
double delta = y - Math.nextDown(y);
这会产生1024。