考虑以下代码:
现在,多亏了 QuickCheck,我知道了一个神奇的数字(为了方便,我已经对齐了结果):
有些浮点数无法在内存中精确表示,一些操作很容易使浮点数产生“波动”。我们都知道这一点。但是,导致此解析问题的原因似乎不同。
简单介绍一下帮助我发现这个问题的测试...在这些测试中,生成浮点值,打印并解析回来(使用Parsec)。例如,数字9.2被认为是无法表示为浮点值的,然而它通过了测试(显然是由于“智能”打印函数)。为什么4.23808622486133会失败?
现在:
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 ""
现在,多亏了 QuickCheck,我知道了一个神奇的数字(为了方便,我已经对齐了结果):
λ> myTest "4.23808622486133"
Right 4.2380862248613305
有些浮点数无法在内存中精确表示,一些操作很容易使浮点数产生“波动”。我们都知道这一点。但是,导致此解析问题的原因似乎不同。
简单介绍一下帮助我发现这个问题的测试...在这些测试中,生成浮点值,打印并解析回来(使用Parsec)。例如,数字9.2被认为是无法表示为浮点值的,然而它通过了测试(显然是由于“智能”打印函数)。为什么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
x
,它不能准确地表示为浮点数,但当它被打印时,我们得到一个实际打印的数字x'
。那么当你将其解析回来时,你应该再次得到x
。我期望在此方面有某种一致性... - Mark Karpov