2011-12-14 6 views
2
を持って

可能性の重複:
Floating point arithmetic not producing exact results in JavaJavaのダブルの変数が変な値

私はこの単純な割り算をしていたが、私は非常に奇妙な出力が得られます。

double a = 60/(1.2-1.1); 

= > 600.0000000000008

doubleプリミティブは、値の大きな範囲を保持する能力について精度を取引floating pointデータ型であるので、予め

+0

分母に2番目の二重変数を作成してみてください:double b = 1.2-1。1;ダブルa = 60/b;同じ結果ですか? –

+1

あなたは以前の回答のいくつかを[承諾](http://meta.stackexchange.com/q/5234/161469)する必要があります – amit

+0

今日この質問はJavaのタグの中で尋ねられます。 「日付を解析する方法」で最もよく尋ねられる質問でなければなりません。 –

答えて

8

、我々はバイナリ表現で1.1と1.2を考慮する必要があります。私たちは正確にバイナリでそれらを表現するために無限に多くのビットを必要とする

1.2 = 0b1.001100110011001100110011001100110011001100110011001100110011... 
1.1 = 0b1.000110011001100110011001100110011001100110011001100110011001... 

ノート。ダブルのみ意義の53ビットを持って、我々は数字を切り落とすする必要があります。

1.2 = 0b1.001100110011001100110011001100110011001100110011001100110011... 
1.1 = 0b1.000110011001100110011001100110011001100110011001100110011001... 
                  ^round from here 
==> 
1.2 ~ 0b1.0011001100110011001100110011001100110011001100110011 
     (= exactly 1.1999999999999999555910790149937383830547332763671875) 
1.1 ~ 0b1.0001100110011001100110011001100110011001100110011010 
     (= exactly 1.100000000000000088817841970012523233890533447265625) 

したがって1.2から1.1である:

1.2 ~ 0b1.0011001100110011001100110011001100110011001100110011 
- 1.1 ~ 0b1.0001100110011001100110011001100110011001100110011010 
———————————————————————————————————————————————————————————————— 
     0b0.00011001100110011001100110011001100110011001100110010000 
     (= exactly 0.09999999999999986677323704498121514916419982910156250000) 

私たちは、実際に

を与える、まさに60/0.0999999999999998667732370449812151491641998291015625を計算することができます
600.0000000000007993605777301137740672368493927467455286920109359612256820927... 
       ^16th significant figure 

は、OPの結果が

600.0000000000008 
と一致します
+0

うわー。今私はあなたが114kポイントを得た方法を見ます。 – user949300

+0

彼は現在122kポイントです:) –

5

で600

おかげでなければなりません。

任意の精度が必要な場合は、代わりにBigDecimalを使用する必要があります。

4

あなたは浮動小数点演算の驚異を発見しました。数値の内部表現はバイナリであるため、特定の10進数を正確に表現することはできません。結果として、いくつかの算術演算は、最下位桁に予期しない結果を与えます。

これは、数値的な方法のコースなどで詳しく解説されていますが、Wikipedia articleは悪くありません。

+0

+1。私は10進数と1/3の現実世界の例を追加しますが、あなたはそれを私に打ち明けました。 – user949300

1

これは正確に「丸めの問題」ではありません。特定の数値を2進浮動小数点で正確に表すことはできません。誰も無限の紙を持っていないので1/3のように10進数で正確に表すことはできません。 (またはビット)。

+0

チューリングには無限のビットがあったと確信していました...または、少なくとも彼が暗示していることは... –

+0

チューリングマシンの定義には無限のビット数がありますが、購入することをお勧めします。 –

2

正しい結果を得るには、BigDecimalを使用する必要があります。ダブルIEEE-754バイナリで