Loss of precision in large numbers when decoding JSON with Aeson

Hello everyone, I’ve been facing a challenge with number precision using Aeson in my Haskell project.

My data type for handling money looks like this:

import Data.Aeson hiding (json)
import Language.Haskell.TH
import Data.Aeson.TH
import Data.Aeson.Types

data Money = USD Float
$(deriveJSON defaultOptions ''Money)

-- handling data from an HTTP request
_money <- requireCheckJsonBody :: Handler Money

The problem arises when I input a large number, such as USD 1157265240.03. The value that gets parsed is 1,157,265,300.0, which rounds the 240 to 300.

This seems to occur due to conversion from something like Scientific notation to a Float, causing the loss of precision. What are some solutions to avoid this issue and maintain accuracy in the decimal values? Thanks!

Been there with monetary calculations myself. You’re hitting classic floating point precision loss - Float wasn’t designed for this.

What worked for me: I built a custom newtype wrapper around Integer to represent cents directly. Instead of storing 1157265240.03 as a float, I store 115726524003 as an Integer and handle decimal conversion in display logic.

This kills floating point arithmetic completely and gives exact precision. You’ll need custom ToJSON/FromJSON instances, but it’s straightforward - divide by 100 when serializing to JSON, multiply by 100 when parsing.

Financial systems have used this pattern for decades because it’s bulletproof for money calculations.

Float’s the problem here - it can’t handle precision with large numbers. I hit this same issue in financial apps and switching to Rational or Scientific fixed it completely. For your Money type, try Scientific from the scientific package instead of Float. Aeson works with Scientific natively without losing precision. Another option: store monetary values as integers in the smallest unit (cents) and convert for display. This kills floating point math entirely and it’s what most financial systems use when precision matters.

totally! Scientific is nice, but you should really check out Data.Fixed for handling money. it keeps all the precision you need and avoids those frustrating rounding issues. trust me, it’s worth the switch!