{-# LANGUAGE CPP #-}
{-# LANGUAGE NumericUnderscores #-}
module Numeric.Rounded.Hardware.Internal.FloatUtil
  ( nextUp
  , nextDown
  , nextTowardZero
  , distanceUlp
  , fusedMultiplyAdd
  ) where
import           Data.Ratio
import           Numeric.Floating.IEEE

distanceUlp :: RealFloat a => a -> a -> Maybe Integer
distanceUlp :: forall a. RealFloat a => a -> a -> Maybe Integer
distanceUlp a
x a
y
  | forall a. RealFloat a => a -> Bool
isInfinite a
x Bool -> Bool -> Bool
|| forall a. RealFloat a => a -> Bool
isInfinite a
y Bool -> Bool -> Bool
|| forall a. RealFloat a => a -> Bool
isNaN a
x Bool -> Bool -> Bool
|| forall a. RealFloat a => a -> Bool
isNaN a
y = forall a. Maybe a
Nothing
  | Bool
otherwise = let m :: a
m = forall a. Ord a => a -> a -> a
min (forall a. Num a => a -> a
abs a
x) (forall a. Num a => a -> a
abs a
y)
                    m' :: a
m' = forall a. RealFloat a => a -> a
nextUp a
m
                    v :: Rational
v = (forall a. Real a => a -> Rational
toRational a
y forall a. Num a => a -> a -> a
- forall a. Real a => a -> Rational
toRational a
x) forall a. Fractional a => a -> a -> a
/ forall a. Real a => a -> Rational
toRational (a
m' forall a. Num a => a -> a -> a
- a
m)
                in if forall a. Ratio a -> a
denominator Rational
v forall a. Eq a => a -> a -> Bool
== Integer
1
                   then forall a. a -> Maybe a
Just (forall a. Num a => a -> a
abs (forall a. Ratio a -> a
numerator Rational
v))
                   else forall a. HasCallStack => [Char] -> a
error [Char]
"distanceUlp"