質問

を縮小しようとするプログラムがあります double 希望の数値まで下げます。私が得る出力は次のとおりです NaN.

どういうことですか NaN Javaでという意味ですか?

役に立ちましたか?

解決

このページから撮影

  

「NaNは」「ではない数」の略です。 「ナン」   浮動小数点場合に生成されます   操作は、いくつかの入力パラメータがあります   その生産するために操作原因   いくつかの未定義の結果。例えば、   0.0で割った0.0算術未定義です。 Aの平方根を取ります   負の数も定義されています。

他のヒント

NaN 手段 「数字ではない」 基本的には、特殊な浮動小数点値の表現です。 IEE 754浮動小数点 標準。 NaN 一般に、値が有効な浮動小数点数では表現できないものであることを意味します。

変換される値が他の値である場合、たとえば数値を表さない文字列を変換する場合、変換の結果はこの値になります。

NaN手段「非数」とゼロによるゼロ除算例えばような浮動小数点数に未定義の動作の結果です。 (また、通常数学で定義されていないゼロによる非ゼロの数を分割しながら、それがNaNではなく、正または負の無限大になりません)。

NaN手段 "数字ではありません。"それは手段が演算の結果が定義されていないか、実数として表現されていないことという特殊な浮動小数点値です。

を参照してください。ここをこの値のより詳細な説明のために。

NaNはない数を表します。数学的に定義されていない任意の値を表すために使用されています。 0.0によって0.0を分割が挙げられます。 あなたはより多くの情報については、こちらを見ることができます:<のhref =「https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm」のrel = "nofollowをnoreferrer "> https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm の

ポストここにあなたのプログラムあなたはより多くの助けが必要な場合。

はNaN =非数ます。

の手段ではない数。 これは、多くのプログラミング言語では不可能な数値のための一般的な表現です。

が、JSや他の言語ではないのJavaの男は、私はいくつかの操作は、それはない有効な数値になった原因を意味し、それの「非数」を使用します。

これは、文字通り「非数」を意味します。 I容疑者何かコンバージョンプロセスに問題がある。

この参照する

最小限の実行可能な例

まず知っておく必要があるのは、NaN の概念は CPU ハードウェアに直接実装されているということです。

最新の主要な CPU はすべてこれに従うようです IEEE 754 これは浮動小数点形式を指定しており、単なる特殊な浮動小数点値である NaN はその標準の一部です。

したがって、この概念は、浮動小数点コードを直接 CPU に出力する Java を含め、どの言語でも非常に似ています。

先に進む前に、まず私が書いた次の回答を読んでみてください。

次に、Java アクションについて説明します。コア言語にない重要な関数のほとんどは内部に存在します。 java.lang.Float.

ナンジャワ

import java.lang.Float;
import java.lang.Math;

public class Nan {
    public static void main(String[] args) {
        // Generate some NaNs.
        float nan            = Float.NaN;
        float zero_div_zero  = 0.0f / 0.0f;
        float sqrt_negative  = (float)Math.sqrt(-1.0);
        float log_negative   = (float)Math.log(-1.0);
        float inf_minus_inf  = Float.POSITIVE_INFINITY - Float.POSITIVE_INFINITY;
        float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f;
        float quiet_nan1     = Float.intBitsToFloat(0x7fc00001);
        float quiet_nan2     = Float.intBitsToFloat(0x7fc00002);
        float signaling_nan1 = Float.intBitsToFloat(0x7fa00001);
        float signaling_nan2 = Float.intBitsToFloat(0x7fa00002);
        float nan_minus      = -nan;

        // Generate some infinities.
        float positive_inf   = Float.POSITIVE_INFINITY;
        float negative_inf   = Float.NEGATIVE_INFINITY;
        float one_div_zero   = 1.0f / 0.0f;
        float log_zero       = (float)Math.log(0.0);

        // Double check that they are actually NaNs.
        assert  Float.isNaN(nan);
        assert  Float.isNaN(zero_div_zero);
        assert  Float.isNaN(sqrt_negative);
        assert  Float.isNaN(inf_minus_inf);
        assert  Float.isNaN(inf_times_zero);
        assert  Float.isNaN(quiet_nan1);
        assert  Float.isNaN(quiet_nan2);
        assert  Float.isNaN(signaling_nan1);
        assert  Float.isNaN(signaling_nan2);
        assert  Float.isNaN(nan_minus);
        assert  Float.isNaN(log_negative);

        // Double check that they are infinities.
        assert  Float.isInfinite(positive_inf);
        assert  Float.isInfinite(negative_inf);
        assert !Float.isNaN(positive_inf);
        assert !Float.isNaN(negative_inf);
        assert one_div_zero == positive_inf;
        assert log_zero == negative_inf;
            // Double check infinities.

        // See what they look like.
        System.out.printf("nan            0x%08x %f\n", Float.floatToRawIntBits(nan           ), nan           );
        System.out.printf("zero_div_zero  0x%08x %f\n", Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );
        System.out.printf("sqrt_negative  0x%08x %f\n", Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );
        System.out.printf("log_negative   0x%08x %f\n", Float.floatToRawIntBits(log_negative  ), log_negative  );
        System.out.printf("inf_minus_inf  0x%08x %f\n", Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );
        System.out.printf("inf_times_zero 0x%08x %f\n", Float.floatToRawIntBits(inf_times_zero), inf_times_zero);
        System.out.printf("quiet_nan1     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan1    ), quiet_nan1    );
        System.out.printf("quiet_nan2     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan2    ), quiet_nan2    );
        System.out.printf("signaling_nan1 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan1), signaling_nan1);
        System.out.printf("signaling_nan2 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan2), signaling_nan2);
        System.out.printf("nan_minus      0x%08x %f\n", Float.floatToRawIntBits(nan_minus     ), nan_minus     );
        System.out.printf("positive_inf   0x%08x %f\n", Float.floatToRawIntBits(positive_inf  ), positive_inf  );
        System.out.printf("negative_inf   0x%08x %f\n", Float.floatToRawIntBits(negative_inf  ), negative_inf  );
        System.out.printf("one_div_zero   0x%08x %f\n", Float.floatToRawIntBits(one_div_zero  ), one_div_zero  );
        System.out.printf("log_zero       0x%08x %f\n", Float.floatToRawIntBits(log_zero      ), log_zero      );

        // NaN comparisons always fail.
        // Therefore, all tests that we will do afterwards will be just isNaN.
        assert !(1.0f < nan);
        assert !(1.0f == nan);
        assert !(1.0f > nan);
        assert !(nan == nan);

        // NaN propagate through most operations.
        assert Float.isNaN(nan + 1.0f);
        assert Float.isNaN(1.0f + nan);
        assert Float.isNaN(nan + nan);
        assert Float.isNaN(nan / 1.0f);
        assert Float.isNaN(1.0f / nan);
        assert Float.isNaN((float)Math.sqrt((double)nan));
    }
}

GitHub アップストリーム.

以下を使用して実行します:

javac Nan.java && java -ea Nan

出力:

nan            0x7fc00000 NaN
zero_div_zero  0x7fc00000 NaN
sqrt_negative  0xffc00000 NaN
log_negative   0xffc00000 NaN
inf_minus_inf  0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1     0x7fc00001 NaN
quiet_nan2     0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus      0xffc00000 NaN
positive_inf   0x7f800000 Infinity
negative_inf   0xff800000 -Infinity
one_div_zero   0x7f800000 Infinity
log_zero       0xff800000 -Infinity

このことから、いくつかのことがわかります。

  • 意味のある結果が得られない奇妙な浮動小数点演算は NaN を返します。

    • 0.0f / 0.0f
    • sqrt(-1.0f)
    • log(-1.0f)

    を生成する NaN.

    実際、C では、次のコマンドを使用して、そのような操作でシグナルの発生を要求することができます。 feenableexcept それらを検出するには、Java では公開されていないと思います。 整数のゼロ除算 1/0 ではエラーが発生するのに、浮動小数点 1/0.0 では「Inf」が返されるのはなぜですか?

  • プラスまたはマイナスの無限大の制限に基づく奇妙な演算ですが、NaN の代わりに +- 無限大を与えます。

    • 1.0f / 0.0f
    • log(0.0f)

    0.0 はほぼこのカテゴリに分類されますが、おそらく問題は、プラスまたはマイナスの無限大になる可能性があるため、NaN のままにされました。

  • NaN が浮動小数点演算の入力である場合、出力も NaN になる傾向があります。

  • NaN にはいくつかの値が考えられます 0x7fc00000, 0x7fc00001, 0x7fc00002, 、ただし、x86_64 のみが生成されるようです 0x7fc00000.

  • NaN と無限大は同様のバイナリ表現を持ちます。

    そのうちのいくつかを詳しく見てみましょう。

    nan          = 0x7fc00000 = 0 11111111 10000000000000000000000
    positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
    negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
                                | |        |
                                | |        mantissa
                                | exponent
                                |
                                sign
    

    このことから、IEEE754 が何を規定しているかを確認します。

    • NaN と無限大の両方の指数は == 255 (すべて 1)
    • 無限には仮数 == 0 があります。したがって、可能な無限は 2 つだけです。+ と -、符号ビットで区別される
    • NaN には仮数部 != 0 があります。したがって、無限である仮数 == 0 を除いて、いくつかの可能性があります。
  • NaN は正または負 (最上位ビット) のいずれかになりますが、これは通常の動作には影響しません。

Ubuntu 18.10 amd64、OpenJDK 1.8.0_191 でテスト済み。

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