double或float数据类型在循环中没有正确加起来?

时间:2012-05-07 11:19:01

标签: java for-loop floating-point floating-accuracy

在循环中,我添加0.10,直到达到所需的#,并获得索引。这是我的代码:

    private static int getIndexOfUnits(float units) {
    int index = -1;
    float addup = 0.10f;
    for(float i = 1.00f; i < units; i=(float)i+addup) {
        index++;
        System.out.println("I = " + i + " Index = " + index);
    }

    return index;
}

如果通过的单位是5.7,我看到的输出是:

I = 1.0 Index = 0
I = 1.1 Index = 1
I = 1.2 Index = 2
I = 1.3000001 Index = 3
I = 1.4000001 Index = 4
I = 1.5000001 Index = 5
I = 1.6000001 Index = 6
I = 1.7000002 Index = 7
I = 1.8000002 Index = 8
I = 1.9000002 Index = 9
I = 2.0000002 Index = 10
I = 2.1000001 Index = 11
I = 2.2 Index = 12
I = 2.3 Index = 13
I = 2.3999999 Index = 14
I = 2.4999998 Index = 15
I = 2.5999997 Index = 16
I = 2.6999996 Index = 17
I = 2.7999995 Index = 18
I = 2.8999994 Index = 19
I = 2.9999993 Index = 20
I = 3.0999992 Index = 21
I = 3.199999 Index = 22
I = 3.299999 Index = 23
I = 3.399999 Index = 24
I = 3.4999988 Index = 25
I = 3.5999987 Index = 26
I = 3.6999986 Index = 27
I = 3.7999985 Index = 28
I = 3.8999984 Index = 29
I = 3.9999983 Index = 30
I = 4.0999985 Index = 31
I = 4.1999984 Index = 32
I = 4.2999983 Index = 33
I = 4.399998 Index = 34
I = 4.499998 Index = 35
I = 4.599998 Index = 36
I = 4.699998 Index = 37
I = 4.799998 Index = 38
I = 4.8999977 Index = 39
I = 4.9999976 Index = 40
I = 5.0999975 Index = 41
I = 5.1999974 Index = 42
I = 5.2999973 Index = 43
I = 5.399997 Index = 44
I = 5.499997 Index = 45
I = 5.599997 Index = 46
I = 5.699997 Index = 47

如果单位是18.90或29.90这样的大数字,它会给出错误的指数。索引通常比应该少1。最初只增加了0.10,但是在2.3之后,它增加了0.10,获得了2.39999 ....我相信这是一个精确的问题。无论使用float还是double,如何处理它并确保我在big#上获得正确的索引。

任何想法!!!!

5 个答案:

答案 0 :(得分:12)

来自Floating-Point Guide

  

为什么我的数字,如0.1 + 0.2加起来不是很好的一轮0.3,而且   相反,我得到一个奇怪的结果,如0.30000000000000004?

     

因为在内部,计算机使用格式(二进制浮点)   它不能准确地表示0.1,0.2或0.3之类的数字。

     

编译或解释代码时,您的“0.1”已经存在   四舍五入到该格式的最接近的数字,这导致一个小的   甚至在计算发生之前就会出现舍入错误。

如果您需要数字来添加exaclty,则无法使用floatdouble。请改用BigDecimal

答案 1 :(得分:1)

问题是float使用的格式不能代表所有十进制数,因此有时会丢失精度。

改为使用BigDecimal

答案 2 :(得分:1)

Float数据类型不具备精确表示。

BigDecimal会对您有所帮助。下面的示例可能会对您有所帮助

BigDecimal decimal=new BigDecimal(10.0);
    for (int i = 0; i < 10; i++) {
        decimal=decimal.add(new BigDecimal(.1));
        System.out.println(decimal.floatValue());

    }

答案 3 :(得分:0)

你不应该使用float来做这种事情(索引/迭代)。

每次尝试计算我:

I = 1.0f + (i*addup);

并且你不会累积浮点错误。

答案 4 :(得分:0)

我认为这可能是您正在寻找的:

Java提供了一个来自导入包的类: import java.text.DecimalFormat ,名为 DecimalFormat 。它的签名是:

DecimalFormat myFormat = new DecimalFormat("0.0");

它需要一个String参数,您可以在其中指定格式的显示方式。

以下是将其应用于代码的方法:

DecimalFormat myFormat;
private static int getIndexOfUnits(float units) {
myFormat = new DecimalFormat("0.0");
int index = -1;
float addup = 0.10f;
for(float i = 1.00f; i < units; i=(float)i+addup) {
    index++;
    System.out.println("I = " + myFormat.format(i) + " Index = " + index);
}

return index;

}

在你的println中,你可以看到使用对DecimalFormat的myFormat对象引用在format()上调用了DecimalFormat的类float i方法 - 这就是格式化的地方。