Skip to content

Commit

Permalink
Make / slightly more efficient
Browse files Browse the repository at this point in the history
  • Loading branch information
basvandijk committed May 11, 2018
1 parent 3b1a59f commit cad7388
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
9 changes: 9 additions & 0 deletions bench/bench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ main = defaultMain
, benchRead "12345678900000000000.12345678900000000000000000"
, benchRead "12345678900000000000.12345678900000000000000000e1234"
]

, bgroup "division"
[ bench (show n ++ " / " ++ show d) $ nf (uncurry (/)) t
| t@(n, d) <-
[ (0.4 , 20.0)
, (0.4e-100, 0.2e50)
] :: [(Scientific, Scientific)]
]

]
where
pos :: Fractional a => a
Expand Down
2 changes: 2 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
efficient than using `scientific` because no expensive normalization has to be
performed.

* Make / on Scientifics slightly more efficient.

0.3.6.2
* Due to a regression introduced in 0.3.4.14 the RealFrac methods
and floatingOrInteger became vulnerable to a space blowup when
Expand Down
16 changes: 12 additions & 4 deletions src/Data/Scientific/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ unsafeScientificFromNormalized = Scientific
-- because no expensive normalization has to be performed.
unsafeScientificFromNonNormalized
:: Integer -- ^ coefficient
-> Int -- ^ number of trailing 0s in the coefficient
-> Int -- ^ number of trailing 0s in the coefficient. This should be positive!
-> Int -- ^ base-10 exponent
-> Scientific
unsafeScientificFromNonNormalized 0 _ _ = Scientific 0 0
Expand Down Expand Up @@ -265,15 +265,23 @@ instance Real Scientific where
-- | /WARNING:/ 'recip' and '/' will throw an error when their outputs are
-- <https://en.wikipedia.org/wiki/Repeating_decimal repeating decimals>.
--
-- These methods also compute 'Integer' magnitudes (@10^e@). If these methods
-- are applied to arguments which have huge exponents this could fill up all
-- space and crash your program! So don't apply these methods to scientific
-- numbers coming from untrusted sources.
--
-- 'fromRational' will throw an error when the input 'Rational' is a repeating
-- decimal. Consider using 'fromRationalRepetend' for these rationals which
-- will detect the repetition and indicate where it starts.
instance Fractional Scientific where
recip = fromRational . recip . toRational
{-# INLINABLE recip #-}

x / y = fromRational $ toRational x / toRational y
{-# INLINABLE (/) #-}
Scientific c1 e1 / Scientific c2 e2
| d < 0 = fromRational (x / (fromInteger (magnitude (-d))))
| otherwise = fromRational (x * fromInteger (magnitude d))
where
d = e1 - e2
x = c1 % c2

fromRational rational =
case mbRepetendIx of
Expand Down

0 comments on commit cad7388

Please sign in to comment.