on master help sign in
Encode RealFloat numbers using Scientific.fromFloatDigits

The previous code used realToFrac (fromRation . toRational) which approximates a floating point value. For example: > toRational (1.2::Double) 5404319552844595 % 4503599627370496 If you encode this Rational number to a Scientific number and render it you get: > encode (1.2::Double) "1.1999999999999999555910790149937383830547332763671875" Using Scientific.fromFloatDigits you get the expected: > encode (1.2::Double) "1.2"

commit5db3aa617ef6021737e082fc7a979c7859999b16 authorBas van Dijk <v.dijk.bas@gmail.com> dateTue 5 Nov 2013, 01:42 (13 years ago) parente202fb4
1 file changed+5−4
Data/Aeson/Types/Instances.hs+5−4
Data/Aeson/Types/Instances.hs+5−4
@@ -55,7 +55,8 @@ import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
5555import Data.Aeson.Functions
5656import Data.Aeson.Types.Class
5757import Data.Aeson.Types.Internal
58−import Data.Scientific (Scientific, coefficient, base10Exponent)
58+import Data.Scientific (Scientific)
59+import qualified Data.Scientific as Scientific (coefficient, base10Exponent, fromFloatDigits)
5960import Data.Attoparsec.Number (Number(..))
6061import Data.Fixed
6162import Data.Hashable (Hashable(..))
@@ -158,7 +159,7 @@ instance ToJSON Double where
158159realFloatToJSON :: RealFloat a => a -> Value
159160realFloatToJSON d
160161 | isNaN d || isInfinite d = Null
161− | otherwise = Number $ realToFrac d
162+ | otherwise = Number $ Scientific.fromFloatDigits d
162163{-# INLINE realFloatToJSON #-}
163164
164165instance FromJSON Double where
@@ -780,6 +781,6 @@ scientificToNumber s
780781 | e < 0 = D $ fromInteger c / 10 ^ negate e
781782 | otherwise = I $ c * 10 ^ e
782783 where
783− e = base10Exponent s
784− c = coefficient s
784+ e = Scientific.base10Exponent s
785+ c = Scientific.coefficient s
785786{-# INLINE scientificToNumber #-}