我这里有一个简单的代码,但是它没有任何除法或复杂的乘法。
for ( double i=.1; i<=1; i+=.1) {
System.out.println(i);
}
但在某些情况下, 的值i
并不准确,例如.79999999
或.600000001
。
为什么会这样?我怎样才能改变这个变得准确的代码?
我这里有一个简单的代码,但是它没有任何除法或复杂的乘法。
for ( double i=.1; i<=1; i+=.1) {
System.out.println(i);
}
但在某些情况下, 的值i
并不准确,例如.79999999
或.600000001
。
为什么会这样?我怎样才能改变这个变得准确的代码?
浮点数不能精确表示,它们会失去精度。尝试
for ( int i=1; i<=10; i+=1) {
System.out.println("%.f", (double)i/10);
}
double
不精确 - 它旨在保持有限的准确性。
对于精确的“双打”,请使用BigDecimal
:
BigDecimal d = new BigDecimal(".1");
for ( BigDecimal i= d; ! i.equals(BigDecimal.ONE) ; i = i.add(d) {
System.out.println(i);
}
在循环内使用int
将解决问题:
for (int i=1;i<=10;i++) {
System.out.println(i*0.1);
}
发生这种情况是因为小数部分可能会失去精度,它们没有被精确表示。
您可能想了解每位计算机科学家应该了解的关于浮点运算的更多信息。
这是 的一个众所周知的属性double
。
以 0.x * 2^y(或 1.x * 2^x)的格式存储数字。
这意味着并非所有整数都可以精确表示,最重要的是,
并非所有小数都可以精确表示。
我猜你应该在BigDecimal
这里使用类似的东西。
for (double i = .1; i <= 1; i += .1) {
System.out.println(BigDecimal.valueOf(i).setScale(1, RoundingMode.HALF_UP));
}
这是因为浮点运算。如果你想要精确的值,有特殊的类,比如BigDecimal