Java中的双增量
可能重复:
如何在Java中以0.1f的增量在0.1f和1.0f之间进行迭代?
我的程序的一部分需要在while循环中使用值:
0.1
0.2
0.3
…
0.9
所以我需要在循环中提供它们。 这是代码:
double x = 0.0; while ( x<=1 ) { // increment x by 0.1 for each iteration x += 0.1; }
我需要输出完全正确:
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
但它实际上给了我一些类似的东西:
0.1
0.2
0.300000000000000000000000004
0.4
0.5
0.6
0.79999999999999999999999999
0.89999999999999999999999999
0.99999999999999999999999999
欢迎来到浮点世界,其中0.1不是0.1。 问题是很多数字,包括0.1,都不能用double
表示。 因此,每次循环时,您并没有真正添加0.1到x
。
一种方法是使用整数运算并除以10:
int i = 0; while (i <= 10) { double x = i / 10.0; . . . i++; }
另一种方法是使x
成为BigDecimal
,您可以在其中指定您想要特定的精度。 它基本上是做上面的循环所做的(一个整数加一个刻度),但打包在一个很好的类中,有很多铃声和口哨声。 哦,它具有任意精度。
要获得所需的输出,可以使用DecimalFormat
。 这是一些示例代码。
import java.text.DecimalFormat; public class DF { public static void main(String [] args) { double x = 0.1; DecimalFormat form = new DecimalFormat("#.#"); while (x <= .9) { System.out.println(Double.valueOf(form.format(x))); x += 0.1; } } }
就您现在的实现而言,由于浮点数的性质,无法保证打印的精度。
使用BigDecimal
double x = 0.0; int decimalPlaces = 2; while ( x<=1 ) { x += 0.1; BigDecimal bd = new BigDecimal(x); bd = bd.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP); x = bd.doubleValue(); System.out.println(x); }
您需要使用小数格式化程序来获得预期的输出。
以下是生成预期输出的代码:
import java.text.DecimalFormat; public class FloatIncrement { public static void main (String args[]){ double x= 0.0; DecimalFormat form = new DecimalFormat("#.#"); while(x<0.9){ x= x+0.1; System.out.println("X : "+Double.valueOf(form.format(x))); } } }
那是因为您可以使用二进制浮点进行精确的十进制运算,因为FP无法精确表示所有十进制值。
你需要使用一个整数值来表示一些十进制小数单位,如百分之一或千分之一,或者使用类似BigDecimal的东西。
Double以二进制forms存储
浮点数和双重存储数字作为一定数量的有效数字和小数点(有点像科学记数法)。 重要的数字部分并不总是完美的,因为它存储为一定数量的二进制数字 – 所以你不能指望它以你期望的方式执行。 (有关更好的解释,请参阅http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html )
考虑使用像BigDecimal这样的类或实现有理数的类,就像这里提到的那样 – Java中是否有常用的有理数字库?
您也可以将i转换为整数,并将其从1更改为10,并在代码中对此进行补偿。