2011-05-07 122 views
3

可能重複:
Manipulating and comparing floating points in java比較浮點數

我應該而在Java中比較浮點數使用的ε? Float.compare(float f1,float f2)靜態方法是否可以安全使用?

謝謝!

編輯:我想我明白了。

當我編寫3.6f的日食時,編譯器將這個數字解釋爲3.6。但是,當我編寫1.2f * 3.0f時,結果是3.6000001。雖然在數學上這是錯誤的,但這兩個結果顯然是不平等的。因此在檢查平等時需要有一個epsilon。

但是,當我在eclipse中寫入0.0f時,編譯器會嚴格將其解釋爲0,因爲IEEE 754能夠正確處理它。因此,確保浮動是正確的(值> 0.0f)是正確的。

我看到的唯一問題是當計算機不使用IEEE 754表示形式,而是使用不正確處理0的表示形式。

我對不對?

+1

問題的答案取決於你想要做什麼。事實上,你是否應該使用浮點數也取決於它。解釋手頭的問題,只有這樣你才能得到有用的答案。 – 2011-05-07 20:07:01

+0

以什麼方式安全?這是一個方便的方法,可以處理一些邊緣情況,但它不會阻止你或我創建自己的錯誤。另外,我在試圖實現我自己的等於浮點數的方法時使用了一個epsilon,但在比較它們時沒有。 – 2011-05-07 20:07:22

+0

對不起,不夠具體。我正在爲遊戲寫作粒子。我想知道deltaTime(float)何時等於0.0,因爲我使用velocity = distance *(1/deltaTime)來計算速度。擁有無限的速度有點愚蠢。 現在我使用(Float.compare(deltaTime,0.0f)!= 0)來確保deltaTime大於0.0。 deltaTime不能小於0. – Klems 2011-05-07 20:23:34

回答

3

是的,建議使用公差來檢查兩個浮點數之差的絕對值。

比較告訴你,如果一個double小於,等於或大於另一個。它不會告訴你他們彼此有多接近,所以,沒有,它比==更安全。

+0

+1,如果你不喜歡,還原我的編輯;-) – aioobe 2011-05-07 20:25:29

+0

不,這很好。 – duffymo 2011-05-07 20:28:36

12

Math.ulp()方法在測試中有實際用處。正如你毫無疑問知道的那樣,你通常不應該比較浮點數以確保相等。相反,你檢查他們在一定的容忍度內是否相等。例如,在JUnit的你比較預期的實際浮點值,像這樣:

assertEquals(expectedValue, actualValue, 0.02);

此斷言,實際值在預期值的0.02。然而,0.02是否合理?如果預期值是10.5或-107.82,那麼0.02可能是好的。但是,如果預期值是幾十億,那麼0.02可能與零完全無法區分。通常應該測試的是ULP方面的相對誤差。根據計算需要多少準確度,通常選擇1到10個ULP之間的某個公差。例如,在這裏我指定實際結果必須是真實值的5個ULPS內:

assertEquals(expectedValue, actualValue, 5*Math.ulp(expectedValue));

http://www.ibm.com/developerworks/java/library/j-math2/index.html

+0

如果一個值大而另一個小?採取總和的ULP是一個好主意? – Winter 2017-05-16 16:51:10