fp-ieee-0.1.0: src/Numeric/Floating/IEEE/Internal/Remainder.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Numeric.Floating.IEEE.Internal.Remainder
( remainder
) where
import MyPrelude
import Numeric.Floating.IEEE.Internal.Classify
default ()
-- |
-- @'remainder' x y@ returns \(r=x-yn\), where \(n\) is the integer nearest the exact number \(x/y\); i.e. \(n=\mathrm{round}(x/y)\).
--
-- IEEE 754 @remainder@ operation.
remainder :: RealFloat a => a -> a -> a
remainder x y | isFinite x && isInfinite y = x
| y == 0 || isInfinite y || isNaN y || not (isFinite x) = (x - x) / y * y -- return a NaN
| otherwise = let n = round (toRational x / toRational y)
r = fromRational (toRational x - toRational y * fromInteger n)
in r -- if r == 0, the sign of r is the same as x
{-# NOINLINE [1] remainder #-}
#if defined(USE_FFI)
foreign import ccall unsafe "remainderf"
c_remainderFloat :: Float -> Float -> Float
foreign import ccall unsafe "remainder"
c_remainderDouble :: Double -> Double -> Double
{-# RULES
"remainder/Float" remainder = c_remainderFloat
"remainder/Double" remainder = c_remainderDouble
#-}
#endif