考慮下面的代碼:浮點數,精度,秒差距
import Text.Parsec
import Text.Parsec.Language
import Text.Parsec.String
import qualified Text.Parsec.Token as Token
float :: Parser Double
float = Token.float (Token.makeTokenParser emptyDef)
myTest :: String -> Either ParseError Double
myTest = parse float ""
現在,由於快速檢查我知道一個神奇的數字(我已經對準結果爲 方便):
λ> myTest "4.23808622486133"
Right 4.2380862248613305
某些浮點數不能在內存中精確表示,有些操作很容易將「波動」引入浮點數。我們 都知道。但是,這個解析問題的原因似乎有所不同。
有關幫助我發現此功能的測試的幾句話。簡單地說, 在這些測試中浮點值被生成,打印並解析回 (帶有Parsec)。例如,數字9.2
被稱爲impossible to represent as floating point value, 然而它通過了測試(顯然是因爲「智能」打印 功能)。爲什麼4.23808622486133
失敗?
對於那些誰相信這些數字都是相同的,4.23808622486133
是4.2380862248613305
只是簡短明確表示:
a1 :: Double
a1 = 9.2000000000000003
a2 :: Double
a2 = 9.200000000000001
b1 :: Double
b1 = 4.23808622486133
b2 :: Double
b2 = 4.2380862248613305
現在:
λ> a1 == a2
True
λ> b1 == b2
False
有些人會再次不同意,但我會一直說:當你使用浮點時,你應該永遠不要期望任何東西都是完全相等的。 – leftaroundabout
@leftaroundabout,絕對正確。然而,有趣的是爲什麼這種事情在解析中發生。我的意思是,假設有一個數字「x」不能完全表示爲浮點數,但當它被打印時,假設有實際打印的「x」號。當你解析它時,你應該再次得到'x'。我期望在那裏有某種一致性...... – Mark
我很遺憾寫下了我的答案。你可以不接受嗎?另一個對Haskell程序員來說似乎更有用。 –