2015-06-24 84 views
1

問題。我有雙「0.4 0.3 2.1等」的字符串。 我需要在此列表中循環並計算每個數字的出現次數。在Java中使用雙循環的循環

我用

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

其中是字符串和orderValues是一個TreeMap。

在此之後,我必須添加到TreeMap從0到最大密鑰值的所有缺失值與0發生。 所以我用

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

問題是雙重迭代。我只需要迭代double值的第一個小數。 這是輸出。

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值


我如何修正(感謝羅埃爾)迭代上雙。 我已經改變了對語句轉換成

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

可能重複[浮點數學是否被破壞?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Dragondraikk

+1

在那個筆記上,它看起來像你使用雙打作爲地圖的關鍵值,由於浮點算術本身的原因,這有點棘手。也許你可能會考慮使用'BigDecimal'來代替它,它也可以解決你的迭代問題。 – Dragondraikk

回答

1

您使用的是原始的雙和類類型雙,有一個轉換他們之間的事,他們既浮點,你看到浮點不精確。

1

雙類型精度的缺乏是衆所周知的。通常,解決方案是使用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 這不是那麼容易,因爲雙重使用,但更安全。