Open lippling opened 7 years ago
As mentioned on /r/haskell:
I'm not entirely clear on what you want to accomplish. But if you want to convert scientific values to a fixed precision you can just use Data.Fixed as in:
> realToFrac (2.8987623864723 :: Scientific) :: Fixed E2
2.89
Do be aware that realToFrac
can be dangerous when applied to a Scientific coming from an untrusted source. See the docs for details.
Sorry for double posting, I was not sure if issues are read.
I get a float/double from an unstrusted source (JSON) which gets parsed into a scientific
value (aeson
). I want to store it into a database column as an INT
with a predefined exponent.
For example:
2.7864 -> parse -> convert to 27864 -> save to db 2.7 -> parse -> convert to 27000 -> save to db 2.78648 -> parse -> convert to 27865 or 27864 -> save to db 2 -> parse -> convert to 20000 -> save to db
And of course I need to use it the other way around: fetch from db, do some calculations, send back to client as json number.
I'm thinking of adding the following function:
toBoundedFractional
:: (Fractional a)
=> Integer -- ^ low bound
-> Integer -- ^ high bound
-> Scientific
-> Maybe a
toBoundedFractional lo hi s
| c == 0 = Just 0
| e > limit && e > hiLimit = Nothing
| e < -limit && e < loLimit && e + d < loLimit = Just 0
| otherwise = Just $ realToFrac s
where
c = coefficient s
e = base10Exponent s
d = integerLog10' (abs c)
loLimit = integerLog10' lo
hiLimit = integerLog10' hi
You can then define the helper function:
toIntBoundedFixed :: (HasResolution a) => Scientific -> Maybe (Fixed a)
toIntBoundedFixed = toBoundedFractional (toInteger (minBound :: Int))
(toInteger (maxBound :: Int))
and a resolution type for your desired resolution:
data E4
instance HasResolution E4 where
resolution _ = 10000 -- | resolution of 10^-4 = .0001
Then you can use it as follows:
λ (\(MkFixed i) -> i) <$> (toIntBoundedFixed 2.7864 :: Maybe (Fixed E4))
Just 27864
I haven't thought this through properly yet so the API might change.
Would this work for you?
Sorry for the delay. Right now I'm busy with another issue, but I'll come back to it in a few days and give feedback.
I want to store a scientific value in the database using a predefined base (e.g. 2.56 as 256 with predefined exponent of -2). When I retrieve the value from the database I construct the scientific value with scientific 256 (-2). I also get values from the JSON parser and they have arbitrary exponents, e.g. 2.8987623864723 has exponent -13. How can I convert the scientific value with exponent -13 to -2 so it has the right coefficient which can be saved to database? I haven't found a utility function for that.