9

可能重复:
如何在 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.3000000000000000000000000004

0.4

0.5

0.6

0.79999999999999999999999999

0.89999999999999999999999999

0.99999999999999999999999999

4

6 回答 6

13

欢迎来到浮点世界,0.1 不是 0.1。问题是很多数字,包括 0.1,不能在double. 因此,您并没有真正在x每次循环中添加 0.1。

一种方法是使用整数算术并除以 10:

int i = 0;
while (i <= 10) {
    double x = i / 10.0;
    . . .
    i++;
}

另一种方法是制作x一个BigDecimal,您可以在其中指定您想要特定的精度。它基本上是在做上面的循环所做的事情(一个整数加上一个比例),但是打包在一个漂亮的类中,有很多花里胡哨的东西。哦,它具有任意精度。

于 2012-12-12T04:40:55.383 回答
2

您需要使用十进制格式化程序来获得预期的输出。

下面是生成预期输出的代码:

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)));          

        }

    }
}
于 2012-12-12T05:05:22.937 回答
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); 
  }
于 2012-12-12T04:40:22.733 回答
1

要获得您想要的输出,您可以使用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;
    }

  }

}

就您现在的实现而言,由于浮点数的性质,无法保证打印的精度。

于 2012-12-12T04:48:51.453 回答
0

那是因为您可以使用二进制浮点数来进行精确的十进制运算,因为 FP 不能精确地表示所有十进制值。

您需要使用一个整数值来表示一些十进制小数单位,例如百分之一或千分之一,或者使用 BigDecimal 之类的东西。

于 2012-12-12T04:42:06.370 回答
0

Double 以二进制形式存储

floatdouble将数字存储为一定数量的有效数字和小数点(有点像科学记数法)。有效数字部分并不总是完美的,因为它存储为一定数量的二进制数字 - 所以你不能指望它按照你期望的方式执行。(有关更好的解释,请参见http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

考虑使用诸如 BigDecimal 之类的类或实现有理数的类,就像这里提到的那样 - Java 中是否有常用的有理数库?

您也可以将 i 转换为整数,然后将其从 1 更改为 10,并在您的代码中对此进行补偿。

于 2012-12-12T04:43:24.703 回答