有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中带双精度的Forloop

问题。我有一串双“0.4 0.3 2.1等”。 我需要在这个列表中循环并计算每个数字的出现次数

我曾经

StringTokenizer stokens = new StringTokenizer(values);
while(stokens.hasMoreTokens()) {
    Double tempKey = new Double(stokens.nextToken());
    Integer tempCount = orderValues.get(tempKey);
    if (tempCount == null) 
        tempCount = 1;
    else 
        tempCount++;
    orderValues.put(tempKey, tempCount);
}

其中,values是字符串,orderValues是树映射

在此之后,我必须添加到树映射中所有缺失的值,从0到出现率为0的最大键值。 所以我用

for(double i = 0; i<=orderValues.lastKey(); i+=0.1) {
    if (orderValues.get(new Double(i))==null) {
        orderValues.put(i,0);
    }
}

问题是双精度上的迭代。我需要迭代双精度值的第一个小数点。 这是输出

0.0 => 0
0.1 => 0
0.2 => 0
0.30000000000000004 => 0
0.4 => 0
0.5 => 1
0.6 => 1
0.7 => 0
0.7999999999999999 => 0
0.8999999999999999 => 0
0.9999999999999999 => 0
1.0999999999999999 => 0
1.2 => 2
1.3 => 0
1.4 => 2
1.4000000000000001 => 0
etc..

当然这是个问题(看看1.4和1.4000000001)。 我怎样才能防止这种情况

主要问题是用0.1的值对double进行迭代


我是如何修复的(感谢Roel)。 我已将for语句更改为

for(double i = 0.1; i<=orderValues.lastKey(); i=rounding(0.1+i)) {

并增加了舍入功能

private double rounding(double x) {
    BigDecimal bd = new BigDecimal(x);
    bd = bd.setScale(1, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

共 (2) 个答案

  1. # 1 楼答案

    您正在使用原语double和类类型double,它们之间正在进行转换,因为它们都是浮点,所以您会看到浮点不精确

  2. # 2 楼答案

    双精度类型的精度不足是众所周知的。通常,解决方案是使用BigDecimal。然而,在您的特定情况下,由于您在每次迭代中步进0.1,您也可以使用整数,并在需要时将它们除以10

    请注意,还应更改存储数据的方式。即使用:

    TreeMap<BigDecimal, Integer>
    
    (or TreeMap<Integer, Integer>) instead of TreeMap<Double, Integer>
    

    另请参见BigDecimal的文档:http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html 它不像double那样容易使用,但更安全