2012-12-27 85 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