質問

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 とは異なりますが、これらをゼロ以外から減算しても元の数値は変わりません。

役に立ちましたか?

解決

MIN_NORMAL Javadoc に記載されているように、これは正規化された最小値のみです double 価値。しかし、それは次のようなものであるという意味ではありません 1 のために ints:浮動小数点値の場合は、次のようになります。 いいえ 次の表現可能な値に変更するために追加できる標準の「eps」。「eps」は常に、指定された浮動小数点値の指数に依存します。それが彼らが呼ばれる理由です フローティング 最後にポイント:)

ただし、Java 1.6 以降では、 Math.nextAfter() 与えられた場合に返されるもの double, 、次または前の表現可能 double.

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

他のヒント

ダブルは限られた精度を持っています。min_normalは2e-1022です。それを追加しない限り、2E-1000のBallparkにも入らない限り落とされます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top