在Java中将Java打印到System.out

时间:2013-12-02 14:11:27

标签: java double

此代码无法正常工作。

a=-1;   
b=0.1;   
for(i=0;i<=20;i++){  
    System.out.println(i + ". x= " + a);   
    a=a+b;   
}       

在控制台上我应该看到:

0. x= -1.0  
1. x= -0.9  
2. x= -0.8  
3. x= -0.7  
4. x= -0.6  
5. x= -0.5  
6. x= -0.4  
7. x= -0.3  

...等

但这就是发生的事情:

0. x= -1.0  
1. x= -0.9  
2. x= -0.8  
3. x= -0.7000000000000001  
4. x= -0.6000000000000001  
5. x= -0.5000000000000001  
6. x= -0.40000000000000013  
7. x= -0.30000000000000016  
8. x= -0.20000000000000015  
9. x= -0.10000000000000014  
10. x= -1.3877787807814457E-16  
11. x= 0.09999999999999987  
12. x= 0.19999999999999987  
13. x= 0.2999999999999999  
14. x= 0.3999999999999999  
15. x= 0.4999999999999999  
16. x= 0.5999999999999999  
17. x= 0.6999999999999998  
18. x= 0.7999999999999998  
19. x= 0.8999999999999998  
20. x= 0.9999999999999998  

我在这里做错了什么?

6 个答案:

答案 0 :(得分:4)

这里有什么浮点不准确。由于double的精度有限,因此无法精确表示所有十进制数。特别是0.1是一个重复的二进制文件,因此所有有限长度的二进制表示将是不准确的。这意味着计算机无法存储您正在使用的数字。

您可以通过格式化输出来修复输出(例如System.out.format("%d. x=%.1f", i, a);),也可以使用BigDecimal代替double来修正数字。或者,您可以通过每次计算a而不是累积(并且每次都添加增量错误)来减少问题的规模,例如, a = i/10.0。这取决于你想要达到的目标。

重要的“带回家信息”是不能依赖双打来提供完整准确的答案,你应该期待浮点运算中的小错误。

答案 1 :(得分:2)

当您需要精确度时:使用BigDecimal代替double

有关详细信息,请参阅此问题:Double vs. BigDecimal?

编辑:如果你不需要精确度;你可以格式化输出..

答案 2 :(得分:2)

尝试格式化输出:

for(i=0;i<=20;i++){  
    System.out.format("%d. x=%.1f", i, a);   
    a=a+b;   
}  

有关格式化输出的详细信息,请参阅docs

答案 3 :(得分:1)

我最喜欢的是使用System.out.printf()
就像它的C对应物一样,你定义了你要传递给它的变量的类型,然后就把它变成了那种类型的东西。例如 System.out.printf("%.1f", yourDouble);

应该做的伎俩。

资源: Printf cheat sheet

答案 4 :(得分:0)

您可能正在为每个对象使用整数。相反,当你去显示它们时,首先调用这个方法:

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = new BigDecimal(value);
    bd = bd.setScale(places, BigDecimal.ROUND_HALF_UP);
    return bd.doubleValue();
}

或者使用正确类型的对象而不是整数...

答案 5 :(得分:0)

使用String.format或者只是在system.out.println中使用十进制格式化语法,你应该看到你想要的东西。 浮点运算以不同的方式在内部表示。因此,对这些值的简单打印并不总是让您希望您需要屏幕视图格式的内容。