Java语言的计算不准确?

时间:2016-01-27 13:26:59

标签: java

我尝试了以下for循环:

for(double i = 0.0; i<=0.001; i+=0.0001)
    System.out.println(i);

我得到以下输出:

  

0.0
  1.0E-4
  2.0E-4
  3.0000000000000003E-4
  4.0E-4
  5.0E-4
  6.000000000000001E-4
  7.000000000000001E-4
  8.000000000000001E-4
  9.000000000000002E-4

我的问题是:

  • 这些额外的.000000000000001是如何来的?
  • 这些额外的数字是否会出现,或者我的代码中是否存在问题?
  • 这些错误是仅在Java语言或任何其他编程语言中发生的吗?
  • double是否适合for循环?

2 个答案:

答案 0 :(得分:6)

可悲的是,并非所有数字都可以在floating point中完全表示:

  

例如,十进制数0.1不能用二进制表示   任何有限精度的浮点数;确切的二进制   表示将有一个“1100”序列无休止地继续:

     

e = -4; s = 1100110011001100110011001100110011 ...,其中,as   以前,s是有效数,e是指数。

     

当舍入到24位时,这变为

     

e = -4; s = 110011001100110011001101,实际上是   0.100000001490116119384765625(十进制)。

答案 1 :(得分:1)

尝试使用BigDecimal,这是我的示例代码:

import java.math.BigDecimal;

public class Test {

    private static final BigDecimal UPPER_LIMIT = new BigDecimal(0.001);
    private static final BigDecimal STEPS = new BigDecimal(0.0001);

    public static void main(String[] args) {
        for(BigDecimal i = BigDecimal.ZERO; i.compareTo(UPPER_LIMIT) != 1; i = i.add(STEPS)){
            System.out.printf("%.4f\n", i);
        }

    }

}

输出是:

0.0000
0.0001
0.0002
0.0003
0.0004
0.0005
0.0006
0.0007
0.0008
0.0009

P.S。我没有花时间进行内存管理和其他细节,应该比使用原语更加繁重