2012-02-03 9 views
-1

可能性の重複:
Retain precision with Doubles in java
Floating point inaccuracy examples(倍精度/オブジェクトの一意性)

私はに関連する正当な理由があることを知っていますオブジェクトと二重引用符がJavaに格納されているため、このif文がfalseになります。私の理解はなんらかの理由で、.3の代わりに実際には0.29999999です。なぜこの条件式が偽を返すのか、さらに直感的に私に説明する人もいますか?

public class hello { 
    public static void main(String[] args) { 

     double a = 0.1; 
     double b = 0.1; 
     double c = 0.3; 

     if(a+b+a == c) 
      System.out.println("if is true"); 
    } 
} 
+4

http://docs.oracle.com/cd/E19957-01 /806-3568/ncg_goldberg.html – Mysticial

答えて

1

BigDecimalを使用して、実際の値が何であるかを確認できます。

double a = 0.1; 
double c = 0.3; 

System.out.println(a + " is actually " + new BigDecimal(a)); 
System.out.println(c + " is actually " + new BigDecimal(c)); 
double a3 = a * 3; 
System.out.println("0.1 * 3 or " + a3 + " is actually " + new BigDecimal(a3)); 
double ac = a + c; 
System.out.println("0.1 + 0.3 or " + ac + " is actually " + new BigDecimal(ac)); 

プリント

0.1 is actually 0.1000000000000000055511151231257827021181583404541015625 
0.3 is actually 0.299999999999999988897769753748434595763683319091796875 
0.1 * 3 or 0.30000000000000004 is actually 0.3000000000000000444089209850062616169452667236328125 
0.1 + 0.3 or 0.4 is actually 0.40000000000000002220446049250313080847263336181640625 

あなたが見ることができるように、doubleは正確に0.1を表現することはできません。 0.1の値を出力すると、表現エラーを隠す小さな丸めが行われます。これは、丸めのない計算を実行し、表現エラーが蓄積されているのを見ることができる場合を除いて、上手く見えます。

0.1 * 3は、目に見える程度の大きさのエラーになります。ただし、0.1 + 0.3は0.4と同じになります(これは、0.1の誤差がわずかに大きすぎ、0.3の誤差がわずかに小さすぎるためです)

0

のJava(私は他のプログラミング言語を考える)正確な精度でfloatdoubleを表すものではありません。この記事を読むComparing floating point numbers Javaでは、BigDecimalを使用することになっています。