2012-12-27 127 views
0

我有這個功能。簡單的運動計算給出了錯誤的結果

Calculations.add(this, //CONTEXT 
     function() { //CALUCATE 
      this.position.x += (this.movementSpeed.x/10); 
     }, 
     function() { //HAVE CALCULATED 
      return (this.position.x === (tempX + this.movementSpeed.x)); 
     } 
    ); 

我已經運行了結果,但有時候結果是錯誤的。因爲我知道如果它計算10次,那麼HAVE CALCULATED應該是真的。

但有時它永遠不會......並殺死我的應用程序。

讓我們說,結果應該給138,然後經過計算它給我138.000000000006這是不是138和HAVE CALCULATED是假的..

如何管理這個= I不能使用圓形,因爲它應該能夠返回138.5,如果最終結果是這樣的話。

希望你能理解我的問題。

+3

這是浮點數固有的預期行爲。請閱讀http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html。將您的數字截斷到一定的小數位數以減輕浮點錯誤。 –

+0

我得花一些時間,112頁是很多。 :-) – TryingToImprove

回答

0

您不應該以這種方式比較浮點值。 (從瓦利德·汗在評論中的鏈接提供了一個很好的解釋,爲什麼出現這種情況)

相反,你可以做這樣的事情來檢查a平等和b

if (a < b + 0.0001 && a > b - 0.0001) { 
    // values are "equal" 
} 
+0

這個解決方案很簡單,可以工作。 :-) – TryingToImprove

1

始終浮點=比較應做過這樣的:

Math.abs(a - b) < 1e-6

其中1e-6爲您提前

0確定任意誤差閾值
+0

通常稱爲'epsilon'或什麼,在硬件限制[機器epsilon](http://en.wikipedia.org/wiki/Machine_epsilon)後。 –

+0

在快速瀏覽http://www.beastin.name/professional/Threshold%20estimates%20for%20arbitrary%20error%20models.pdf後,我認爲我無法做這種比較。 :) – TryingToImprove

0

你可以四捨五入到一定數量的數字,從另一個answer上所以用這樣的:

function roundNumber(n, digits) { 
    var multiple = Math.pow(10, digits); 
    return Math.round(n * multiple)/multiple;; 
} 

這樣你就不需要花哨的比較。

+0

你會如何確定數字? – TryingToImprove

+0

這取決於你的問題,因爲你的問題「因爲它應該能夠返回138.5」,數字將是1.你決定什麼水平,你想回合。 – tomdemuyt