2014-03-04 69 views
0

在我的2D物理模擬(Java)中,我計算凸多邊形的中心如下,其中參數區域是以前計算的多邊形的封閉區域。避免算法中的浮點精度錯誤

private Vector2d calculateCenterOfMass(double area) { 
    Vector2d center = new Vector2d(0, 0); 

    for (int i = 0; i < vertices.length; i++) { 
     int j = (i + 1) % vertices.length; 
     double factor = (vertices[i].x * vertices[j].y 
         - vertices[j].x * vertices[i].y); 
     center.x += (vertices[i].x + vertices[j].x) * factor; 
     center.y += (vertices[i].y + vertices[j].y) * factor; 
    } 
    center.scale(1/(area * 6)); 

    return center; 
} 

我進一步有以下幾點我用的函數計算的質心的多邊形:

Vector2d [x=325.20399446366355, y=400.0, length=515.5168649182318] 
Vector2d [x=375.20399446366355, y=400.0, length=548.4323453822622] 
Vector2d [x=375.20399446366355, y=450.0, length=585.8993407245727] 
Vector2d [x=325.20399446366355, y=450.0, length=555.2095442399406] 

正如你可以通過查看Ÿ值中心看到必須在y = 425.0。由於浮點魔法,y值變爲425.00000000000017。作爲參數給出的面積具有確切的值2500.0

我該如何避免這種情況,並得到我預期的425.0?

+2

使用'java.math.BigDecimal'而不是雙精度值 –

+1

您應該閱讀[每位計算機科學家有關浮點運算的知識](http://docs.oracle.com/cd/E19957-01/806- 3568/ncg_goldberg.html) – hivert

+0

如果您不需要那麼高的精度,您可以將數字四捨五入到小數點後兩位... – assylias

回答

3

BigDecimal可以幫助,但我會建議閱讀整個答案。

從某種意義上講,浮點錯誤是'正常的',您不能將每個浮點數確切的存儲在一個變量中。有很多資源在那裏這裏怎麼處理這個問題,幾個環節:

  1. 如果你不知道實際的問題是哪些檢查this出來。
  2. What Every Computer Scientist Should Know About Floating-Poit Arithmetic
  3. IEEE floating point
  4. 給你一個idead如何工作的:Quantity Pattern
+0

您的鏈接確實有助於理解問題。所以你會得到印記!我最終得到一個演員陣容,然後回到雙重位置。用浮點精度對數值的大小進行四捨五入。你有什麼想法我可以達到更高的精度(float

1

使用雙重計算和長期儲存。