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