2

私はjdk1.6を使用しています。これは私のコードです。

float f = 10.0f;

double d = 10.0; 

System.out.println("Equal Status : " + (f == d)); 

次に、システムは答えをとして表示しますtrue。しかし、値を次のように変更した場合

float f = 10.1f; 

double d = 10.1; 

System.out.println("Equal Status : " + (f == d));

その後、システムは答えをfalseとして表示します。システムが==チェックにビットマッチングを使用していることを知っています。しかし、背後にある理由は何ですか。それについて説明してもらえますか?前もって感謝します。

4

7 に答える 7

1

これは「私の」答えではありませんが、これは「meh」から「good」に移行したいプログラマーにとって「必読」の文献にほぼ近いものです。素晴らしいことは本当に特別なことなので、「良い」とはくしゃみをするものだとは思わないでください。:)

すべてのプログラマーが浮動小数点について知っておくべきこと

于 2012-07-12T03:31:47.050 に答える
1

@Samが提案したリンクは素晴らしいですが、それでも私には技術的すぎます:P

浮動小数点の処理についてOPにいくつか意見を述べます(おそらく、背後にある理由を尋ねているため、少しトピックから外れています。背後にある理由については、@ Samが提案したリンクを読んでください)。

浮動小数点数が正確な表現を提供するとは限りません。時々それはできますが、常にではありません。浮動小数点には、最初のn桁目が「正確」である「有効数字」に制約があります。

フロートとダブルを混合しているため、状況はさらに悪化しますが、解決する考え方は似ています。

アプリケーションが計算結果に必要な精度を決定し、それに基づいてイプシロン値を決定する必要があります。たとえば、アプリケーションの精度は小数点以下3桁までで十分であり、おそらく0.0005のイプシロンが妥当です。

2つの浮動小数点数の比較は、によって行われるべきではなく==、を使用する必要があります (a + EPSILON > b && a - EPSILON < b)。同様に、次のa > bように表現する必要がありますa - EPSILON > b

于 2012-07-12T04:02:08.830 に答える
1

覚えておくべきポイントは

  1. 10.1は、バイナリ1010101010の繰り返しシーケンスです。
  2. フロートとダブルを比較する場合、数字を埋めるためにzerroを追加することにより、フロートはダブルに変換されます

    比較します

    1010101 ...00000000...から1010101.....101010...までは異なります。

    float f = 10.1f;

    ダブルd=10.1;

    System.out.println( "Equal Status:" +(f ==(float)d));

本当の答えを与えるでしょう

于 2012-07-12T04:59:48.250 に答える
1

IMHO、一般的に言えば、ユースケースの99%doubleは、より正確であるため、より適切な選択です。つまり、必要がないfloat限り使用しないでください。

floatBigDecimalを使用して、またはの実際の表現を表示できますdoubletoStringは少量の丸めを実行するため、これは通常は表示されません(型表現の制限に対応するようにコーディングされているため)。

System.out.println("10.1f is actually " + new BigDecimal(10.1f));
System.out.println("10.1 is actually " + new BigDecimal(10.1));

プリント

10.1f is actually 10.1000003814697265625
10.1 is actually 10.0999999999999996447286321199499070644378662109375

double値が目的の10.1に近いことがわかりますが、正確にはこの値ではありません。値が異なる理由は、いずれの場合も、そのタイプに最も近いresprentable値を持っているためです。

于 2012-07-12T06:52:54.047 に答える
0

floatは32ビットタイプdoubleですが、は64ビットタイプです。

あなたは古典的な浮動小数点の精度の問題に遭遇しました。

于 2012-07-12T03:27:58.360 に答える
0

フロートは不正確です。10.1fと10.1の実際の値は、四捨五入によりわずかに異なります。フロートは10進数ではなく2進数であるため、10.1のように「単純」に見える数値は、フロートとして正確に表すことはできません。

于 2012-07-12T03:28:17.267 に答える
0

32ビットと64ビットの両方の浮動小数点表現のIEEE浮動小数点標準を更新することをお勧めします。この内部を覗くと、なぜこれらのフローティングポイントが気難しい振る舞いをするのかがはっきりとわかります。

内部でどのように表現されるか(これが失敗する理由)に興味がある場合は、これらの数値の16進表現を示すこのコードを使用できます。そこから、それらを単精度および倍精度の指数および仮数と一致させることができます。

System.out.printf("Float 10.0: 0x%X\n", Float.floatToRawIntBits((float)10.0));
System.out.printf("Double 10.0: 0x%X\n", Double.doubleToRawLongBits(10.0));
System.out.printf("Float 10.1: 0x%X\n", Float.floatToRawIntBits((float)10.1));
System.out.printf("Double 10.1: 0x%X\n", Double.doubleToRawLongBits(10.1));

プリント

Float 10.0: 0x41200000
Double 10.0: 0x4024000000000000
Float 10.1: 0x4121999A
Double 10.1: 0x4024333333333333

値の表現方法に繰り返しがあることに気付くでしょう。これは、2を底とする有限空間では1/10を表現できないためです。

于 2012-07-12T04:11:07.650 に答える