2012-08-02 57 views
-1

(這個問題是問在Ruby範圍內,但如果它是在一個更一般的方式回答,我也不會難過。)斷言與存儲/檢索浮點數

所以(幾乎)每個人都知道在比較涉及數學計算平等浮點數是一個不走,你必須測試範圍(在Ruby中,像這樣):

assert_in_delta 5.0, 3.5+1.5, 0.0001 

然而,就是這樣還是有必要的時候健全檢查浮動當它從一個子系統傳遞到另一個子系統時,是否指向等號的點號(在Ruby上下文中)如此?

json={:foo => 0.5}.to_json 
# POST the JSON to a Rails controller, that puts it in a Mongo database 
found_obj=pull_obj_out_of_Mongo # details not important here 
assert_in_delta 0.5, found_obj[:foo], 0.0001 

我個人認爲是assert_in_delta仍然是一個好主意,在這裏,因爲我不知道,也許很多人不知道,無論是概念上的浮點值0.5沿的方式通過了將使它能夠與等於0.5的浮點數字0.5進行比較。實際上是這樣嗎?或者我對浮點數的存儲和傳遞方式太偏執了?答案的多少取決於使用哪種語言?

+0

順便說一句,'5.0 ==(3.5 + 1.5)'返回'true'。像'Math :: acos(1.0/Math :: sqrt(2))== Math :: PI/4'這樣的情況會返回錯誤,因爲大約有'1e-16'的差異。包含非常大和非常小的數字的總和也是有問題的:'2.0e19 + 5.0 - 2.0e19'結果爲0.0,而不是5.0(雙精度沒有足夠的精度位,所以5.0被捨去)。 – sfstewman 2012-08-03 03:42:23

回答

0

這很大程度上取決於子系統與Float的作用。在Ruby(至少1.8和1.9)中,Floats簡單地包裝一個雙精度數字(字面上C是double,在大多數現代體系結構中作爲IEEE 754 double-precision number存儲)。當您傳遞數字或在該表示中複製數字時,這些位不會更改。

但是,當您將Float傳遞到子系統時,它可能會更改基礎表示形式。在你給出的例子中,你使用JSON序列化數字,這涉及到將float轉換爲字符串,然後將其轉換回來。不能保證你能夠恢復15-16位以上的精度(假設你用這種精度進行轉換)。這似乎很多,但僅僅確保所有可能的浮點值的嚴格平等是不夠的。