Reputation: 33
I have some code that uses Centi
for its currency type. It receives Double
s from an Excel spreadsheet using the xlsx package. I want to convert these Double
s into Centi
s correctly. I have tried using realToFrac
, and for the most part it works, but occasionally it's out by a cent:
λ realToFrac (-1372.92 :: Double) :: Centi
-1372.93
I can guess that the problem is in the binary representation of that decimal number not being exact, and that I shouldn't be using Double
to represent currency in the first place, but I don't have control of that part. So what is a fail-safe way of doing the conversion?
Upvotes: 3
Views: 369
Reputation: 33399
Maybe not the best way but one is to round
to the closest integer after adjusting for the desired precision:
floatToCenti :: Double -> Centi
floatToCenti = floatToFixed
floatToFixed :: HasResolution a => Double -> Fixed a
floatToFixed x = y where
y = MkFixed (round (fromInteger (resolution y) * x))
-- reusing y as the dummy argument of resolution
Upvotes: 2