2016-06-24 7 views
5

多くの場所で説明されているように(Why can't decimal numbers be represented exactly in binary?など)、すべての小数部分を浮動小数点値として表すことはできません(Javaではfloatに格納されているなど)。JavaのラウンドトリップString - > float - > Stringでも(一部の)値はfloatとして表現できません。

与えられる典型的な例は、「0.2」である。このnifty IEEE 754 Converterによれば、0.2に最も近いfloatは約0.20000000298023224であるので、floatとして「0.2」を解析すると、この結果が得られるはずです。 >フロート - - >文字列往復の文字列の

結果:0.2

String number="0.2"; 
float f = Float.parseFloat(number); 
System.out.println("Result of roundtrip String -> float -> String: "+f); 

プリント:

しかし、私は、Javaが不可能を行うことができるように思われることに注意しました

Test on IDeone.com

Javaは私が望むことをどのように知っていますか上記の正確な出力 "0.20000000298023224"の代わりに(丸められた)出力 "0.2"?小数メートルの一部またはのために印刷する必要がありますどのように多くの桁

Javadocs of Float.toString()はこれを説明してみては? は、小数部分を表す数字が少なくとも1桁でなければなりません。 は、float型の隣接値と引数の値を一意に区別するために必要な桁数を超えています。

残念ながら、これはさらに混乱します。 「引数値を一意に識別するために必要な桁数で印刷する」がJavaに「0.2」を印刷できるのはなぜですか?

答えはで、なぜこの印刷アルゴリズムが選択されたのかを理想的に説明します。この例のように(いくつかの)往復作業をするのですか?別のモチベーションはありますか?

+1

Jon Skeetが必要なときはどこですか?彼はブレイクしましたか? – GhostCat

+0

0.21や0.2000001などの値を入力しても、同様の値が返されます。 http://stackoverflow.com/questions/17464675/convert-string-to-decimal-number-with-2-decimal-places-in-java – mylenereiners

+0

7つのゼロ、10^7 = 2^23がありますので、おそらく4バイト浮動小数点の3バイトの仮数に達する。だからここにはまだ定期的かもしれない。 CとC++はより良い結果を得るためにちょっとしたことをしています(私の印象)。 –

答えて

1

0.2は「Value Set Conversion」に属していると思います。

+0

異なる(しかし、関連する)領域。バリューセットコンバージョンは、FP計算の中間結果に適用され、コンバージョンには適用されないようです。 – sleske

+0

同じページの§5.2を見てください。 – mauretto

2

出力の丸めは、印刷アルゴリズムの一部ではありません。それはfloatのサイズのためです。そうした場合:

String fs = "0.2"; 
double f = Float.parseFloat(fs); 
System.out.println(f); 

あなたが得る:

0.20000000298023224

Test on Ideone.com

これは明らかに文字列 "0.2" は0.20000000298023224として解析されていることを示しているが、浮動小数点データ-typeはそれを保持することができず、0.2まで丸めます。 doubleデータ型はこのデータを保持することができます。したがって、をfloatとして解析するととなりますが、はdoubleに格納されます。

+0

私はそれをダブルとして解析すると、それでも0.2 – 4castle

+0

という結果になりました。私のIDEではこれがあります。待って、私はそれをオンラインで試してみてください。 – Hackerdarshi

+0

@ 4castleこれを参照してください:http://ideone.com/sjWAZS – Hackerdarshi

関連する問題