[Java]NaN与NaN比较是否相等

产生值为NaN的double类型变量d1和Double类型变量d2,使用==、equals()进行比较,结果如注释:

double d1 = 0.0/0.0;
Double d2 = 0.0/0.0;

System.out.println(d1 == d1);//false
System.out.println(d2.equals(d1));//true

当d1与自身进行==比较时判断为false不相等,可以简单认为:

double类型值中的NaN表示“不是一个数”,NaN参与数值比较时可以为任意值,所以d1 == d1为false;

但是d2.equals(d1)为什么返回为true呢?打开Double重写的equals():

public boolean equals(Object obj) {
        return (obj instanceof Double)
               && (doubleToLongBits(((Double)obj).value) ==
                      doubleToLongBits(value));
}

可以看到equals()方法里不是简单地比较obj.doubleValue()返回的double值,而是比较doubleToLongBits()方法的返回值,继续查看该方法:

/**
     * Returns a representation of the specified floating-point value
     * according to the IEEE 754 floating-point "double
     * format" bit layout.
     *
     * <p>Bit 63 (the bit that is selected by the mask
     * {@code 0x8000000000000000L}) represents the sign of the
     * floating-point number. Bits
     * 62-52 (the bits that are selected by the mask
     * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
     * (the bits that are selected by the mask
     * {@code 0x000fffffffffffffL}) represent the significand
     * (sometimes called the mantissa) of the floating-point number.
     *
     * <p>If the argument is positive infinity, the result is
     * {@code 0x7ff0000000000000L}.
     *
     * <p>If the argument is negative infinity, the result is
     * {@code 0xfff0000000000000L}.
     *
     * <p>If the argument is NaN, the result is
     * {@code 0x7ff8000000000000L}.
     *
     * <p>In all cases, the result is a {@code long} integer that, when
     * given to the {@link #longBitsToDouble(long)} method, will produce a
     * floating-point value the same as the argument to
     * {@code doubleToLongBits} (except all NaN values are
     * collapsed to a single "canonical" NaN value).
     *
     * @param   value   a {@code double} precision floating-point number.
     * @return the bits that represent the floating-point number.
     */
public static long doubleToLongBits(double value) {
        long result = doubleToRawLongBits(value);
        // Check for NaN based on values of bit fields, maximum
        // exponent and nonzero significand.
        if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
              DoubleConsts.EXP_BIT_MASK) &&
             (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
            result = 0x7ff8000000000000L;
        return result;
}

方法通过位运算区分了一般值和0x7ff8000000000000L,备注(21行)中对这个值进行了解释:“If the argument is NaN, the result is{@code 0x7ff8000000000000L}.”。同时,在备注(27行)也能清楚的看到“all NaN values are collapsed to a single "canonical" NaN value”

值为NaN的double变量传入doubleToLongBits()方法,返回特殊值。equals()返回对两个相同特殊值==比较的结果,所以d2.equals(d1)判断为true。

通对float、Float类型进行相同测试,结果相同。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值