2013-05-30 30 views
4

我有一个奇怪的数据类型问题:double。在双数据类型中计算不需要的部分

这里是我的代码:

public class Example { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     double a = 1.0; 
     for(int i =0; i<10;i++){ 
      System.out.println("Number => " + a); 
      a += 0.1; 
     } 
    } 

} 

输出应该是:

Number => 1.0 
Number => 1.1 
Number => 1.2 
Number => 1.3 
Number => 1.4 
Number => 1.5 
Number => 1.6 
Number => 1.7 
Number => 1.8 
Number => 1.9 

但是,此代码示例的结果是:

Number => 1.0 
Number => 1.1 
Number => 1.2000000000000002 
Number => 1.3000000000000003 
Number => 1.4000000000000004 
Number => 1.5000000000000004 
Number => 1.6000000000000005 
Number => 1.7000000000000006 
Number => 1.8000000000000007 
Number => 1.9000000000000008 

我用EC lipse来编译这个代码块。我在netbeans上试过,但没有任何改变。

它应该如何发生?有任何想法吗?

Regards

+2

这只是一个精度问题。 –

+4

如果短小数的确切表示对您很重要,那么您应该使用BigDecimal,而不是double。 Double是基于二进制分数的,对十或其权力并不特别重要。这是一种更广泛的存储和处理大量数字的有用近似方法。 –

+0

我正在寻找这个很长一段时间。几乎每个人都认为bigDecimal就是解决方案。但我只是想知道为什么会发生这种情况。顺便说一句,我的que是dup,我没有注意到其他问题。 – alicanbatur

回答

1

这并不容易。我会用公地数学

for (int i = 0; i < 10; i++) { 
    a = Precision.round(a, 1); // <- round to 1 digit after decimal point 
    ... 

我想唯一的Java SE替代是

a = Double.parseDouble(String.format(Locale.US, "%.1f", a)); 
+0

感谢您的回复。当我使用小数字时它非常有用。但我正在研究一个关于计算金钱的项目。 – alicanbatur

+0

@alicanbatur不要使用'Double'。使用'BigDecimal',请参阅http://stackoverflow.com/questions/285680/representing-monetary-values-in-java –

+0

然后使用BigDecimal,原始双倍对金钱没有好处 –

0

根据javadoc的

If at least one of the operands to a numerical operator is of type double, then the operation is carried out using 64-bit floating-point arithmetic, and the result of the numerical operator is a value of type double. If the other operand is not a double, it is first widened (§5.1.5) to type double by numeric promotion (§5.6).

Here is the Source