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();
}
# 1 楼答案
您正在使用原语double和类类型double,它们之间正在进行转换,因为它们都是浮点,所以您会看到浮点不精确
# 2 楼答案
双精度类型的精度不足是众所周知的。通常,解决方案是使用BigDecimal。然而,在您的特定情况下,由于您在每次迭代中步进0.1,您也可以使用整数,并在需要时将它们除以10
请注意,还应更改存储数据的方式。即使用:
另请参见BigDecimal的文档:http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html 它不像double那样容易使用,但更安全