2012-06-18 40 views
0

可能重複:
Java float division precision的Android未能在基本的數學

我試圖修復我的遊戲之一的錯誤,並且需要計算,最佳的瓷磚尺寸。爲此,我得到設備的屏幕分辨率,該級別的行數和列數,然後計算允許我的遊戲使用最大屏幕空間的拼貼大小。然而,Android似乎在基礎數學上失敗了,在簡單的劃分操作上失去了精確性。下面是相應的代碼:

while(!foundIt) 
    { 
     int tileArea = boxes*i*i; //Boxes = 20*26 
     float ratio = displayArea/tileArea; //displayArea = width*height 
     Log.d("Balance", displayArea + "/" + tileArea); 
     Log.d("Balance", boxes + ", " + i); 
     Log.d("Balance", "Ratio: " + ratio); 
     int last = 0; 
     if(ratio>1) 
     { 
      if(last==LAST_WAS_LESS_THAN_ONE) 
      { 
       i--; 
       foundIt=true; 
      } 
      last = LAST_WAS_MORE_THAN_ONE; 
     } 
     else if(ratio==1) 
     { 
      Log.d("Balance", "Found a perfect fit!!"); 
      foundIt=true; 
     } 
     else if(ratio<1) 
     { 
      if(last==LAST_WAS_MORE_THAN_ONE) 
      { 
       i--; 
       foundIt=true; 
      } 
      last = LAST_WAS_LESS_THAN_ONE; 
     } 
     if(!foundIt) 
     { 
      i++; 
     } 
    } 

這裏是我的歌Nexus S運行示例(分辨率:480×800):

06-18 13:20:45.808: D/Balance(1069): Width: 480 Height: 800 
06-18 13:20:45.808: D/Balance(1069): 384000/520 
06-18 13:20:45.808: D/Balance(1069): 520, 1 
06-18 13:20:45.808: D/Balance(1069): Ratio: 738.0 
06-18 13:20:45.808: D/Balance(1069): 384000/2080 
06-18 13:20:45.808: D/Balance(1069): 520, 2 
06-18 13:20:45.808: D/Balance(1069): Ratio: 184.0 
06-18 13:20:45.808: D/Balance(1069): 384000/4680 
06-18 13:20:45.808: D/Balance(1069): 520, 3 
06-18 13:20:45.808: D/Balance(1069): Ratio: 82.0 
06-18 13:20:45.808: D/Balance(1069): 384000/8320 
06-18 13:20:45.808: D/Balance(1069): 520, 4 
06-18 13:20:45.808: D/Balance(1069): Ratio: 46.0 
06-18 13:20:45.808: D/Balance(1069): 384000/13000 
06-18 13:20:45.808: D/Balance(1069): 520, 5 
06-18 13:20:45.808: D/Balance(1069): Ratio: 29.0 
06-18 13:20:45.808: D/Balance(1069): 384000/18720 
06-18 13:20:45.808: D/Balance(1069): 520, 6 
06-18 13:20:45.808: D/Balance(1069): Ratio: 20.0 
06-18 13:20:45.808: D/Balance(1069): 384000/25480 
06-18 13:20:45.808: D/Balance(1069): 520, 7 
06-18 13:20:45.808: D/Balance(1069): Ratio: 15.0 
06-18 13:20:45.808: D/Balance(1069): 384000/33280 
06-18 13:20:45.808: D/Balance(1069): 520, 8 
06-18 13:20:45.808: D/Balance(1069): Ratio: 11.0 
06-18 13:20:45.808: D/Balance(1069): 384000/42120 
06-18 13:20:45.808: D/Balance(1069): 520, 9 
06-18 13:20:45.808: D/Balance(1069): Ratio: 9.0 
06-18 13:20:45.808: D/Balance(1069): 384000/52000 
06-18 13:20:45.808: D/Balance(1069): 520, 10 
06-18 13:20:45.808: D/Balance(1069): Ratio: 7.0 
06-18 13:20:45.808: D/Balance(1069): 384000/62920 
06-18 13:20:45.808: D/Balance(1069): 520, 11 
06-18 13:20:45.808: D/Balance(1069): Ratio: 6.0 
06-18 13:20:45.808: D/Balance(1069): 384000/74880 
06-18 13:20:45.808: D/Balance(1069): 520, 12 
06-18 13:20:45.808: D/Balance(1069): Ratio: 5.0 
06-18 13:20:45.808: D/Balance(1069): 384000/87880 
06-18 13:20:45.808: D/Balance(1069): 520, 13 
06-18 13:20:45.808: D/Balance(1069): Ratio: 4.0 
06-18 13:20:45.808: D/Balance(1069): 384000/101920 
06-18 13:20:45.808: D/Balance(1069): 520, 14 
06-18 13:20:45.808: D/Balance(1069): Ratio: 3.0 
06-18 13:20:45.808: D/Balance(1069): 384000/117000 
06-18 13:20:45.808: D/Balance(1069): 520, 15 
06-18 13:20:45.808: D/Balance(1069): Ratio: 3.0 
06-18 13:20:45.808: D/Balance(1069): 384000/133120 
06-18 13:20:45.812: D/Balance(1069): 520, 16 
06-18 13:20:45.812: D/Balance(1069): Ratio: 2.0 
06-18 13:20:45.816: D/Balance(1069): 384000/150280 
06-18 13:20:45.816: D/Balance(1069): 520, 17 
06-18 13:20:45.816: D/Balance(1069): Ratio: 2.0 
06-18 13:20:45.816: D/Balance(1069): 384000/168480 
06-18 13:20:45.816: D/Balance(1069): 520, 18 
06-18 13:20:45.816: D/Balance(1069): Ratio: 2.0 
06-18 13:20:45.816: D/Balance(1069): 384000/187720 
06-18 13:20:45.816: D/Balance(1069): 520, 19 
06-18 13:20:45.816: D/Balance(1069): Ratio: 2.0 
06-18 13:20:45.816: D/Balance(1069): 384000/208000 
06-18 13:20:45.816: D/Balance(1069): 520, 20 
06-18 13:20:45.816: D/Balance(1069): Ratio: 1.0 
06-18 13:20:45.816: D/Balance(1069): Found a perfect fit!! 

計算計算器的比例顯示精度的損失。有人知道這是爲什麼嗎?我的執行中有什麼錯誤?

+0

從這裏開始:http://en.wikipedia.org/wiki/Floating_point_arithmetic#Accuracy_problems –

+2

試試這個,而不是'float ratio = displayArea/tileArea;',嘗試將int轉換爲一個float,像這樣,float ratio = displayArea /(float)tileArea;' – Austin

+0

呃,@奧斯汀,這正是我在第三行所做的。 –

回答

2

從打印輸出看來,displayAreatileArea被聲明爲intlong。並且您在做整數除法displayArea/tileArea)之前結果被提升爲float類型並分配給ratio

由於您正在比較一個是否比另一個大,爲什麼不直接比較displayAreatileArea?它比浮點操作更好。

+0

你認爲它是一個整數除法是有​​道理的。但是,我無法直接比較它,因爲我需要知道tileArea何時最接近顯示區域。從邏輯上講,無論哪一個比例最接近1應該使用最接近的tileArea。 –

+1

@RaghavSood:奧斯汀在評論中的投入建議以及由bmusical回答的建議實際上是爲此而努力的。由於它會將其中一個數字轉換爲浮點數,所以會發生浮點數除法。 – nhahtdh

0

似乎類型鑄造問題, 嘗試將您的displayArea轉換爲float。