1

MIN_NORMAL は、「通常の」double に追加できる値であり、数値が変化すると思いました。たとえば、 Double.MIN_NORMAL を 0.1d に追加すると、0.1d とは異なる値が得られますが、私の理解は間違っています。

public static void test(double val) {
    if (val == (val - Double.MIN_NORMAL*1e50d))
        System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
    else
        System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}

生成するもの:

test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000

test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000

test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000

誰かがここで私の論理に反していることを説明してください。MIN_NORMAL に 1e50d を掛けても、同じ数値が得られるということです。

バイナリ表現を確認したところ、1 * Double.MIN_NORMAL は 2 * Double.MIN_NORMAL とは異なりますが、ゼロ以外のものからそれらを減算しても元の数値は変わりません。

4

2 に答える 2

2

MIN_NORMALJavadoc が言うように、最小の正規化されたdouble値のみです。1しかし、それは s のようなものだという意味ではありませんint: 浮動小数点値の場合、次の表現可能な値に変更するために追加できる標準の "eps"はありません。"eps" は常に次の指数に依存します。指定された浮動小数点値。それが、最終的に浮動小数点と呼ばれる理由です:)

ただし、Java 1.6+ は、指定された に対して、次または前の表現可能なMath.nextAfter()を返すものを提供します。doubledouble

古いバージョンの Java では、いつでも をいじってDouble.doubleToLongBits()、その結果をインクリメントまたはデクリメントし、Double.longBitsToDouble();で変換して戻すことができます。これにより、次または前の表現可能なdouble値が取得されます-ほとんどの場合:いくつかの特殊なケース(NaN、無限値)があるため、これは浮動小数点の初心者にはお勧めできません:)

于 2015-03-01T19:48:21.837 に答える