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,并在代码中对此进行补偿。