Javaの浮動小数点平等の分析

Javaの浮動小数点平等の分析

次のような問題が記述されています。
与えられた2つの変数が、ダブルBを倍増、それらに対応する変数は、ダブルは、X梱包のタイプ、ダブルY、Q、次のとおりです。

  1. A、B、X、Yのグループがある場合、== B &&!X.equals(y)を満たしますか?
  2. A、B、X、Yのグループが存在する場合、!= B && x.equals(y)を満たしますか?

一見すると、それは実際には、そのようなA値の存在は、以下のコードを参照してください、不可能です

public static void main() {
    double a = 0.0;
    double b = -0.0;
    double c = Double.NaN;
    double d = Double.NaN;
    Double x = a;
    Double y = b;
    Double z = c;
    Double w = d;
    System.out.println(a == b);         //输出true
    System.out.println(x.equals(y));    //输出false
    System.out.println(c == d);         //输出false
    System.out.println(w.equals(z));    //输出true
}

ダブルタイプはequals実装し、法の==論理演算子は異なります。
ルック==に応じJava8例にオペレータ、Java言語仕様15.21.1浮動小数点平等テスト、対応のIEEE 754規格のため、:

  1. 限りが1であるオペランドであるとしてNaN==式の結果は常に偽である、!=式の結果は常に真です。実際には、場合場合にのみ、xNaN、式がx!=x真です。あなたは使用することができるFloat.NaN方法やDouble.NaN値か否かを判断する方法をNaN
  2. 正および負の0は、例えば、式は、0に等しい0.0==-0.0真です。
  3. さらに、2つの異なる浮動小数点の使用は、==あるいは!=、オペレータが平等を判断した場合、それらが等しくないことを認識する。具体的には、正の値は無限大、負の無限大を表す値を示し、それらは、それ自体と比較した場合、等しい;他の値が等しくないと比べ。

JDKダブルを見ては、達成するための方法に等しいです。

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

    /**
     * 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;
    }

ダブル方法を等しく==、オペレータ2つのオブジェクトが等しい場合、2つのオブジェクトdoubleToLongBits戻り値と同じであるかを判断します。メソッドのコメントがあります

引数がNaNの場合、結果は0x7ff8000000000000Lです

イコール2を使用して、それを分析しNaN、結果はtrueです。
他の場合には、前記のバイナリ値に応じてdoubleToLongBits戻り値長い対応します。そして、0.0-0.0異なる符号ビットバイナリ表現は、異なるdoubleToLongBits結果が異なっています。

おすすめ

転載: www.cnblogs.com/filozofio/p/12304424.html