问题描述
一些关于 Data.Aeson.Types.Internal.Number
import Data.Aeson
10.4
-- 10.4
realToFrac 10.4
-- 10.4
Number (realToFrac 10.4) -- <-- the problematic expression
-- Number 10.4000000000000003552713678800500929355621337890625
Number 10.4
-- Number 10.4
下面的代码使用有问题的表达式来对 Float
值进行 JSON 编码:
data Value =
VInt Int
| VFloat Float
deriving Show
instance ToJSON Value where
toJSON (VInt n) = Number (fromIntegral n)
toJSON (VFloat f) = Number (realToFrac f)
这将输出带有 10.4000000000000003552713678800500929355621337890625
之类的值的 JSON。
为什么会有这么多带有 Number (realToFrac 10.4)
的尾随数字以及如何解决这个问题?
解决方法
由于种种原因,没有完美的解决方案。您可能喜欢 fromFloatDigits
-- 使用 10.4
会更好,但使用其他数字会更糟。
https://github.com/haskell/aeson/issues/546 中详细讨论了这个一般性问题。讨论并没有真正导致任何结果。如果说有什么要注意的,那就是在 JSON 世界中,数字基本上总是坏的/模棱两可的,如果您想精确,则需要将数据存储在字符串中。