{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Numeric.Floating.IEEE.Internal.Remainder
( remainder
) where
import MyPrelude
import Numeric.Floating.IEEE.Internal.Classify
default ()
remainder :: RealFloat a => a -> a -> a
remainder :: forall a. RealFloat a => a -> a -> a
remainder a
x a
y | forall a. RealFloat a => a -> Bool
isFinite a
x Bool -> Bool -> Bool
&& forall a. RealFloat a => a -> Bool
isInfinite a
y = a
x
| a
y forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
|| forall a. RealFloat a => a -> Bool
isInfinite a
y Bool -> Bool -> Bool
|| forall a. RealFloat a => a -> Bool
isNaN a
y Bool -> Bool -> Bool
|| Bool -> Bool
not (forall a. RealFloat a => a -> Bool
isFinite a
x) = (a
x forall a. Num a => a -> a -> a
- a
x) forall a. Fractional a => a -> a -> a
/ a
y forall a. Num a => a -> a -> a
* a
y
| Bool
otherwise = let n :: Integer
n = forall a b. (RealFrac a, Integral b) => a -> b
round (forall a. Real a => a -> Rational
toRational a
x forall a. Fractional a => a -> a -> a
/ forall a. Real a => a -> Rational
toRational a
y)
r :: a
r = forall a. Fractional a => Rational -> a
fromRational (forall a. Real a => a -> Rational
toRational a
x forall a. Num a => a -> a -> a
- forall a. Real a => a -> Rational
toRational a
y forall a. Num a => a -> a -> a
* forall a. Num a => Integer -> a
fromInteger Integer
n)
in a
r
{-# 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