basvandijk avatar basvandijk committed c12e932

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"

Comments (0)

Files changed (1)

Data/Aeson/Types/Instances.hs

 import Data.Aeson.Functions
 import Data.Aeson.Types.Class
 import Data.Aeson.Types.Internal
-import Data.Scientific (Scientific, coefficient, base10Exponent)
+import Data.Scientific (Scientific)
+import qualified Data.Scientific as Scientific (coefficient, base10Exponent, fromFloatDigits)
 import Data.Attoparsec.Number (Number(..))
 import Data.Fixed
 import Data.Hashable (Hashable(..))
 realFloatToJSON :: RealFloat a => a -> Value
 realFloatToJSON d
     | isNaN d || isInfinite d = Null
-    | otherwise = Number $ realToFrac d
+    | otherwise = Number $ Scientific.fromFloatDigits d
 {-# INLINE realFloatToJSON #-}
 
 instance FromJSON Double where
     | e < 0     = D $ fromInteger c / 10 ^ negate e
     | otherwise = I $ c * 10 ^ e
   where
-    e = base10Exponent s
-    c = coefficient s
+    e = Scientific.base10Exponent s
+    c = Scientific.coefficient s
 {-# INLINE scientificToNumber #-}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.