{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Numeric.Floating.IEEE.Internal.Rounding.Integral where
import Control.Exception (assert)
import Data.Bits
import Data.Functor.Product
import Data.Int
import Data.Proxy
import Data.Word
import GHC.Exts
import Math.NumberTheory.Logarithms (integerLog2', integerLogBase',
wordLog2')
import MyPrelude
import Numeric.Floating.IEEE.Internal.Base
import Numeric.Floating.IEEE.Internal.IntegerInternals
import Numeric.Floating.IEEE.Internal.Rounding.Common
default ()
fromIntegerTiesToEven, fromIntegerTiesToAway, fromIntegerTowardPositive, fromIntegerTowardNegative, fromIntegerTowardZero :: RealFloat a => Integer -> a
fromIntegerTiesToEven :: Integer -> a
fromIntegerTiesToEven = RoundTiesToEven a -> a
forall a. RoundTiesToEven a -> a
roundTiesToEven (RoundTiesToEven a -> a)
-> (Integer -> RoundTiesToEven a) -> Integer -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> RoundTiesToEven a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Integer -> f a
fromIntegerR
fromIntegerTiesToAway :: Integer -> a
fromIntegerTiesToAway = RoundTiesToAway a -> a
forall a. RoundTiesToAway a -> a
roundTiesToAway (RoundTiesToAway a -> a)
-> (Integer -> RoundTiesToAway a) -> Integer -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> RoundTiesToAway a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Integer -> f a
fromIntegerR
fromIntegerTowardPositive :: Integer -> a
fromIntegerTowardPositive = RoundTowardPositive a -> a
forall a. RoundTowardPositive a -> a
roundTowardPositive (RoundTowardPositive a -> a)
-> (Integer -> RoundTowardPositive a) -> Integer -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> RoundTowardPositive a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Integer -> f a
fromIntegerR
fromIntegerTowardNegative :: Integer -> a
fromIntegerTowardNegative = RoundTowardNegative a -> a
forall a. RoundTowardNegative a -> a
roundTowardNegative (RoundTowardNegative a -> a)
-> (Integer -> RoundTowardNegative a) -> Integer -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> RoundTowardNegative a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Integer -> f a
fromIntegerR
fromIntegerTowardZero :: Integer -> a
fromIntegerTowardZero = RoundTowardZero a -> a
forall a. RoundTowardZero a -> a
roundTowardZero (RoundTowardZero a -> a)
-> (Integer -> RoundTowardZero a) -> Integer -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> RoundTowardZero a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Integer -> f a
fromIntegerR
{-# INLINE fromIntegerTiesToEven #-}
{-# INLINE fromIntegerTiesToAway #-}
{-# INLINE fromIntegerTowardPositive #-}
{-# INLINE fromIntegerTowardNegative #-}
{-# INLINE fromIntegerTowardZero #-}
fromIntegralTiesToEven, fromIntegralTiesToAway, fromIntegralTowardPositive, fromIntegralTowardNegative, fromIntegralTowardZero :: (Integral i, RealFloat a) => i -> a
fromIntegralTiesToEven :: i -> a
fromIntegralTiesToEven = RoundTiesToEven a -> a
forall a. RoundTiesToEven a -> a
roundTiesToEven (RoundTiesToEven a -> a) -> (i -> RoundTiesToEven a) -> i -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> RoundTiesToEven a
forall i a (f :: * -> *).
(Integral i, RealFloat a, RoundingStrategy f) =>
i -> f a
fromIntegralR
fromIntegralTiesToAway :: i -> a
fromIntegralTiesToAway = RoundTiesToAway a -> a
forall a. RoundTiesToAway a -> a
roundTiesToAway (RoundTiesToAway a -> a) -> (i -> RoundTiesToAway a) -> i -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> RoundTiesToAway a
forall i a (f :: * -> *).
(Integral i, RealFloat a, RoundingStrategy f) =>
i -> f a
fromIntegralR
fromIntegralTowardPositive :: i -> a
fromIntegralTowardPositive = RoundTowardPositive a -> a
forall a. RoundTowardPositive a -> a
roundTowardPositive (RoundTowardPositive a -> a)
-> (i -> RoundTowardPositive a) -> i -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> RoundTowardPositive a
forall i a (f :: * -> *).
(Integral i, RealFloat a, RoundingStrategy f) =>
i -> f a
fromIntegralR
fromIntegralTowardNegative :: i -> a
fromIntegralTowardNegative = RoundTowardNegative a -> a
forall a. RoundTowardNegative a -> a
roundTowardNegative (RoundTowardNegative a -> a)
-> (i -> RoundTowardNegative a) -> i -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> RoundTowardNegative a
forall i a (f :: * -> *).
(Integral i, RealFloat a, RoundingStrategy f) =>
i -> f a
fromIntegralR
fromIntegralTowardZero :: i -> a
fromIntegralTowardZero = RoundTowardZero a -> a
forall a. RoundTowardZero a -> a
roundTowardZero (RoundTowardZero a -> a) -> (i -> RoundTowardZero a) -> i -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> RoundTowardZero a
forall i a (f :: * -> *).
(Integral i, RealFloat a, RoundingStrategy f) =>
i -> f a
fromIntegralR
{-# INLINE fromIntegralTiesToEven #-}
{-# INLINE fromIntegralTiesToAway #-}
{-# INLINE fromIntegralTowardPositive #-}
{-# INLINE fromIntegralTowardNegative #-}
{-# INLINE fromIntegralTowardZero #-}
fromIntegerR :: (RealFloat a, RoundingStrategy f) => Integer -> f a
fromIntegerR :: Integer -> f a
fromIntegerR Integer
n = case Integer -> Maybe Int
integerToIntMaybe Integer
n of
Just Int
x -> Int -> f a
forall i (f :: * -> *) a.
(Integral i, Bits i, RealFloat a, RoundingStrategy f) =>
i -> f a
fromIntegralRBits Int
x
Maybe Int
Nothing | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 -> a -> a
forall a. Num a => a -> a
negate (a -> a) -> f a -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> Integer -> f a
forall (f :: * -> *) a.
(RealFloat a, RoundingStrategy f) =>
Bool -> Integer -> f a
fromPositiveIntegerR Bool
True (- Integer
n)
| Bool
otherwise -> Bool -> Integer -> f a
forall (f :: * -> *) a.
(RealFloat a, RoundingStrategy f) =>
Bool -> Integer -> f a
fromPositiveIntegerR Bool
False Integer
n
{-# INLINE fromIntegerR #-}
fromIntegralR :: (Integral i, RealFloat a, RoundingStrategy f) => i -> f a
fromIntegralR :: i -> f a
fromIntegralR i
x = Integer -> f a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Integer -> f a
fromIntegerR (i -> Integer
forall a. Integral a => a -> Integer
toInteger i
x)
{-# INLINE [0] fromIntegralR #-}
{-# RULES
"fromIntegralR/Integer->a" fromIntegralR = fromIntegerR
"fromIntegralR/Int->a" fromIntegralR = fromIntegralRBits @Int
"fromIntegralR/Int8->a" fromIntegralR = fromIntegralRBits @Int8
"fromIntegralR/Int16->a" fromIntegralR = fromIntegralRBits @Int16
"fromIntegralR/Int32->a" fromIntegralR = fromIntegralRBits @Int32
"fromIntegralR/Int64->a" fromIntegralR = fromIntegralRBits @Int64
"fromIntegralR/Word->a" fromIntegralR = fromIntegralRBits @Word
"fromIntegralR/Word8->a" fromIntegralR = fromIntegralRBits @Word8
"fromIntegralR/Word16->a" fromIntegralR = fromIntegralRBits @Word16
"fromIntegralR/Word32->a" fromIntegralR = fromIntegralRBits @Word32
"fromIntegralR/Word64->a" fromIntegralR = fromIntegralRBits @Word64
#-}
fromIntegralRBits :: forall i f a. (Integral i, Bits i, RealFloat a, RoundingStrategy f) => i -> f a
fromIntegralRBits :: i -> f a
fromIntegralRBits i
x
| Bool
ieee
, let resultI :: a
resultI = i -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral i
x
, let (Maybe i
min', Maybe i
max') = Proxy a -> (Maybe i, Maybe i)
forall a i.
(Integral i, Bits i, RealFloat a) =>
Proxy a -> (Maybe i, Maybe i)
boundsForExactConversion (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)
, Bool -> (i -> Bool) -> Maybe i -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (i -> i -> Bool
forall a. Ord a => a -> a -> Bool
<= i
x) Maybe i
min'
, Bool -> (i -> Bool) -> Maybe i -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True (i
x i -> i -> Bool
forall a. Ord a => a -> a -> Bool
<=) Maybe i
max'
= a -> f a
forall (f :: * -> *) a. RoundingStrategy f => a -> f a
exact a
resultI
| Bool
ieee
, Integer
base Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
2
, Bool
signed
, Just Int
y <- i -> Maybe Int
forall a b.
(Integral a, Integral b, Bits a, Bits b) =>
a -> Maybe b
toIntegralSized i
x :: Maybe Int
= if Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then
a -> a
forall a. Num a => a -> a
negate (a -> a) -> f a -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> Word -> f a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Bool -> Word -> f a
positiveWordToBinaryFloatR Bool
True (Int -> Word
negateIntAsWord Int
y)
else
Bool -> Word -> f a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Bool -> Word -> f a
positiveWordToBinaryFloatR Bool
False (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
y)
| Bool
ieee
, Integer
base Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
2
, Bool -> Bool
not Bool
signed
, Just Word
y <- i -> Maybe Word
forall a b.
(Integral a, Integral b, Bits a, Bits b) =>
a -> Maybe b
toIntegralSized i
x :: Maybe Word
=
Bool -> Word -> f a
forall a (f :: * -> *).
(RealFloat a, RoundingStrategy f) =>
Bool -> Word -> f a
positiveWordToBinaryFloatR Bool
False Word
y
| Bool
otherwise = f a
result
where
result :: f a
result | i
x i -> i -> Bool
forall a. Eq a => a -> a -> Bool
== i
0 = a -> f a
forall (f :: * -> *) a. RoundingStrategy f => a -> f a
exact a
0
| i
x i -> i -> Bool
forall a. Ord a => a -> a -> Bool
< i
0 = a -> a
forall a. Num a => a -> a
negate (a -> a) -> f a -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> Integer -> f a
forall (f :: * -> *) a.
(RealFloat a, RoundingStrategy f) =>
Bool -> Integer -> f a
fromPositiveIntegerR Bool
True (- i -> Integer
forall a. Integral a => a -> Integer
toInteger i
x)
| Bool
otherwise = Bool -> Integer -> f a
forall (f :: * -> *) a.
(RealFloat a, RoundingStrategy f) =>
Bool -> Integer -> f a
fromPositiveIntegerR Bool
False (i -> Integer
forall a. Integral a => a -> Integer
toInteger i
x)
signed :: Bool
signed = i -> Bool
forall a. Bits a => a -> Bool
isSigned i
x
ieee :: Bool
ieee = a -> Bool
forall a. RealFloat a => a -> Bool
isIEEE (a
forall a. HasCallStack => a
undefined :: a)
base :: Integer
base = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix (a
forall a. HasCallStack => a
undefined :: a)
{-# INLINE fromIntegralRBits #-}
boundsForExactConversion :: forall a i. (Integral i, Bits i, RealFloat a) => Proxy a -> (Maybe i, Maybe i)
boundsForExactConversion :: Proxy a -> (Maybe i, Maybe i)
boundsForExactConversion Proxy a
_ = Bool -> (Maybe i, Maybe i) -> (Maybe i, Maybe i)
forall a. HasCallStack => Bool -> a -> a
assert Bool
ieee (Maybe i
minI, Maybe i
maxI)
where
maxInteger :: Integer
maxInteger = Integer
base Integer -> Int -> Integer
^! Int
digits
minInteger :: Integer
minInteger = - Integer
maxInteger
minI :: Maybe i
minI = case i -> Maybe Integer
forall i. Bits i => i -> Maybe Integer
minBoundAsInteger (i
forall a. HasCallStack => a
undefined :: i) of
Just Integer
minBound' | Integer
minInteger Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
minBound' -> Maybe i
forall a. Maybe a
Nothing
Maybe Integer
_ -> i -> Maybe i
forall a. a -> Maybe a
Just (Integer -> i
forall a. Num a => Integer -> a
fromInteger Integer
minInteger)
maxI :: Maybe i
maxI = case i -> Maybe Integer
forall i. Bits i => i -> Maybe Integer
maxBoundAsInteger (i
forall a. HasCallStack => a
undefined :: i) of
Just Integer
maxBound' | Integer
maxBound' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
maxInteger -> Maybe i
forall a. Maybe a
Nothing
Maybe Integer
_ -> i -> Maybe i
forall a. a -> Maybe a
Just (Integer -> i
forall a. Num a => Integer -> a
fromInteger Integer
maxInteger)
ieee :: Bool
ieee = a -> Bool
forall a. RealFloat a => a -> Bool
isIEEE (a
forall a. HasCallStack => a
undefined :: a)
base :: Integer
base = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix (a
forall a. HasCallStack => a
undefined :: a)
digits :: Int
digits = a -> Int
forall a. RealFloat a => a -> Int
floatDigits (a
forall a. HasCallStack => a
undefined :: a)
{-# INLINE boundsForExactConversion #-}
minBoundAsInteger :: Bits i => i -> Maybe Integer
minBoundAsInteger :: i -> Maybe Integer
minBoundAsInteger i
dummyI = if i -> Bool
forall a. Bits a => a -> Bool
isSigned i
dummyI then
case i -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe i
dummyI of
Just Int
bits -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just (- Int -> Integer
forall a. Bits a => Int -> a
bit (Int
bitsInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1))
Maybe Int
Nothing -> Maybe Integer
forall a. Maybe a
Nothing
else
Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0
{-# INLINE [1] minBoundAsInteger #-}
{-# RULES
"minBoundAsInteger/Int" minBoundAsInteger = (\_ -> Just (toInteger (minBound :: Int))) :: Int -> Maybe Integer
"minBoundAsInteger/Int8" minBoundAsInteger = (\_ -> Just (toInteger (minBound :: Int8))) :: Int8 -> Maybe Integer
"minBoundAsInteger/Int16" minBoundAsInteger = (\_ -> Just (toInteger (minBound :: Int16))) :: Int16 -> Maybe Integer
"minBoundAsInteger/Int32" minBoundAsInteger = (\_ -> Just (toInteger (minBound :: Int32))) :: Int32 -> Maybe Integer
"minBoundAsInteger/Int64" minBoundAsInteger = (\_ -> Just (toInteger (minBound :: Int64))) :: Int64 -> Maybe Integer
"minBoundAsInteger/Word" minBoundAsInteger = (\_ -> Just 0) :: Word -> Maybe Integer
"minBoundAsInteger/Word8" minBoundAsInteger = (\_ -> Just 0) :: Word8 -> Maybe Integer
"minBoundAsInteger/Word16" minBoundAsInteger = (\_ -> Just 0) :: Word16 -> Maybe Integer
"minBoundAsInteger/Word32" minBoundAsInteger = (\_ -> Just 0) :: Word32 -> Maybe Integer
"minBoundAsInteger/Word64" minBoundAsInteger = (\_ -> Just 0) :: Word64 -> Maybe Integer
#-}
maxBoundAsInteger :: Bits i => i -> Maybe Integer
maxBoundAsInteger :: i -> Maybe Integer
maxBoundAsInteger i
dummyI = case i -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe i
dummyI of
Just Int
bits | i -> Bool
forall a. Bits a => a -> Bool
isSigned i
dummyI -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Int -> Integer
forall a. Bits a => Int -> a
bit (Int
bitsInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
| Bool
otherwise -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Int -> Integer
forall a. Bits a => Int -> a
bit Int
bits Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
Maybe Int
Nothing -> Maybe Integer
forall a. Maybe a
Nothing
{-# INLINE [1] maxBoundAsInteger #-}
{-# RULES
"maxBoundAsInteger/Int" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Int))) :: Int -> Maybe Integer
"maxBoundAsInteger/Int8" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Int8))) :: Int8 -> Maybe Integer
"maxBoundAsInteger/Int16" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Int16))) :: Int16 -> Maybe Integer
"maxBoundAsInteger/Int32" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Int32))) :: Int32 -> Maybe Integer
"maxBoundAsInteger/Int64" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Int64))) :: Int64 -> Maybe Integer
"maxBoundAsInteger/Word" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Word))) :: Word -> Maybe Integer
"maxBoundAsInteger/Word8" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Word8))) :: Word8 -> Maybe Integer
"maxBoundAsInteger/Word16" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Word16))) :: Word16 -> Maybe Integer
"maxBoundAsInteger/Word32" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Word32))) :: Word32 -> Maybe Integer
"maxBoundAsInteger/Word64" maxBoundAsInteger = (\_ -> Just (toInteger (maxBound :: Word64))) :: Word64 -> Maybe Integer
#-}
positiveWordToBinaryFloatR :: (RealFloat a, RoundingStrategy f) => Bool -> Word -> f a
positiveWordToBinaryFloatR :: Bool -> Word -> f a
positiveWordToBinaryFloatR Bool
neg (W# Word#
n#) = Bool -> Word# -> f a
forall (f :: * -> *) a.
(RealFloat a, RoundingStrategy f) =>
Bool -> Word# -> f a
positiveWordToBinaryFloatR# Bool
neg Word#
n#
{-# INLINE positiveWordToBinaryFloatR #-}
positiveWordToBinaryFloatR# :: forall f a. (RealFloat a, RoundingStrategy f) => Bool -> Word# -> f a
positiveWordToBinaryFloatR# :: Bool -> Word# -> f a
positiveWordToBinaryFloatR# !Bool
neg Word#
n# = f a
result
where
n :: Word
n = Word# -> Word
W# Word#
n#
result :: f a
result = let k :: Int
k = Word -> Int
wordLog2' Word
n
in if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
fDigits then
a -> f a
forall (f :: * -> *) a. RoundingStrategy f => a -> f a
exact (a -> f a) -> a -> f a
forall a b. (a -> b) -> a -> b
$ Word -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n
else
if Int
expMax Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Word -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Word
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Bool -> Bool -> Bool
&& Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
expMax then
let inf :: a
inf = a
1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
0
in Ordering -> Bool -> Int -> a -> a -> f a
forall (f :: * -> *) a.
RoundingStrategy f =>
Ordering -> Bool -> Int -> a -> a -> f a
inexact Ordering
GT Bool
neg Int
1 a
forall a. RealFloat a => a
maxFinite a
inf
else
let e :: Int
e = Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
fDigits Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
q :: Word
q = Word
n Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
e
r :: Word
r = Word
n Word -> Word -> Word
forall a. Bits a => a -> a -> a
.&. ((Word
1 Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
e) Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1)
towardzero_or_exact :: a
towardzero_or_exact = Word -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
q Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
e)
awayfromzero :: a
awayfromzero = if Word
q Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1 Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== (Word
1 Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
fDigits) Bool -> Bool -> Bool
&& Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Word -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Word
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 then
Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
1 (Word -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize Word
n)
else
Word -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word
q Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1) Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`unsafeShiftL` Int
e)
parity :: Int
parity = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
q :: Int
in Bool -> Ordering -> Bool -> Int -> a -> a -> f a
forall (f :: * -> *) a.
RoundingStrategy f =>
Bool -> Ordering -> Bool -> Int -> a -> a -> f a
doRound
(Word
r Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0)
(Word -> Word -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Word
r (Word
1 Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`unsafeShiftL` (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)))
Bool
neg
Int
parity
a
towardzero_or_exact
a
awayfromzero
!fDigits :: Int
fDigits = a -> Int
forall a. RealFloat a => a -> Int
floatDigits (a
forall a. HasCallStack => a
undefined :: a)
(Int
_expMin, !Int
expMax) = a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange (a
forall a. HasCallStack => a
undefined :: a)
{-# INLINABLE [0] positiveWordToBinaryFloatR# #-}
{-# SPECIALIZE
positiveWordToBinaryFloatR# :: RoundingStrategy f => Bool -> Word# -> f Float
, RoundingStrategy f => Bool -> Word# -> f Double
, RealFloat a => Bool -> Word# -> RoundTiesToEven a
, RealFloat a => Bool -> Word# -> RoundTiesToAway a
, RealFloat a => Bool -> Word# -> RoundTowardPositive a
, RealFloat a => Bool -> Word# -> RoundTowardZero a
, RealFloat a => Bool -> Word# -> Product RoundTowardNegative RoundTowardPositive a
, Bool -> Word# -> RoundTiesToEven Float
, Bool -> Word# -> RoundTiesToAway Float
, Bool -> Word# -> RoundTowardPositive Float
, Bool -> Word# -> RoundTowardZero Float
, Bool -> Word# -> RoundTiesToEven Double
, Bool -> Word# -> RoundTiesToAway Double
, Bool -> Word# -> RoundTowardPositive Double
, Bool -> Word# -> RoundTowardZero Double
, Bool -> Word# -> Product RoundTowardNegative RoundTowardPositive Float
, Bool -> Word# -> Product RoundTowardNegative RoundTowardPositive Double
#-}
{-# RULES
"positiveWordToBinaryFloatR#/RoundTowardNegative"
positiveWordToBinaryFloatR# = \neg x -> RoundTowardNegative (roundTowardPositive (positiveWordToBinaryFloatR# (not neg) x))
#-}
fromPositiveIntegerR :: forall f a. (RealFloat a, RoundingStrategy f) => Bool -> Integer -> f a
fromPositiveIntegerR :: Bool -> Integer -> f a
fromPositiveIntegerR !Bool
neg !Integer
n = Bool -> f a -> f a
forall a. HasCallStack => Bool -> a -> a
assert (Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0) f a
result
where
result :: f a
result = let k :: Int
k = if Integer
base Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
2 then
Integer -> Int
integerLog2' Integer
n
else
Integer -> Integer -> Int
integerLogBase' Integer
base Integer
n
in if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
fDigits then
a -> f a
forall (f :: * -> *) a. RoundingStrategy f => a -> f a
exact (a -> f a) -> a -> f a
forall a b. (a -> b) -> a -> b
$ Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
n
else
if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
expMax then
let inf :: a
inf = a
1 a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
0
in Ordering -> Bool -> Int -> a -> a -> f a
forall (f :: * -> *) a.
RoundingStrategy f =>
Ordering -> Bool -> Int -> a -> a -> f a
inexact Ordering
GT Bool
neg Int
1 a
forall a. RealFloat a => a
maxFinite a
inf
else
let e :: Int
e = Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
fDigits Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
(Integer
q, Integer
r) = Integer -> Integer -> Int -> (Integer, Integer)
quotRemByExpt Integer
n Integer
base Int
e
towardzero_or_exact :: a
towardzero_or_exact = Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
q Int
e
awayfromzero :: a
awayfromzero = Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat (Integer
q Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) Int
e
parity :: Int
parity = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
q :: Int
in Bool -> Ordering -> Bool -> Int -> a -> a -> f a
forall (f :: * -> *) a.
RoundingStrategy f =>
Bool -> Ordering -> Bool -> Int -> a -> a -> f a
doRound
(Integer -> Integer -> Int -> Integer -> Bool
isDivisibleByExpt Integer
n Integer
base Int
e Integer
r)
(Integer -> Integer -> Integer -> Int -> Ordering
compareWithExpt Integer
base Integer
n Integer
r (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
Bool
neg
Int
parity
a
towardzero_or_exact
a
awayfromzero
!base :: Integer
base = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix (a
forall a. HasCallStack => a
undefined :: a)
!fDigits :: Int
fDigits = a -> Int
forall a. RealFloat a => a -> Int
floatDigits (a
forall a. HasCallStack => a
undefined :: a)
(Int
_expMin, !Int
expMax) = a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange (a
forall a. HasCallStack => a
undefined :: a)
{-# INLINABLE [0] fromPositiveIntegerR #-}
{-# SPECIALIZE
fromPositiveIntegerR :: RealFloat a => Bool -> Integer -> RoundTiesToEven a
, RealFloat a => Bool -> Integer -> RoundTiesToAway a
, RealFloat a => Bool -> Integer -> RoundTowardPositive a
, RealFloat a => Bool -> Integer -> RoundTowardZero a
, RealFloat a => Bool -> Integer -> Product RoundTowardNegative RoundTowardPositive a
, RoundingStrategy f => Bool -> Integer -> f Double
, RoundingStrategy f => Bool -> Integer -> f Float
, Bool -> Integer -> RoundTiesToEven Double
, Bool -> Integer -> RoundTiesToAway Double
, Bool -> Integer -> RoundTowardPositive Double
, Bool -> Integer -> RoundTowardZero Double
, Bool -> Integer -> RoundTiesToEven Float
, Bool -> Integer -> RoundTiesToAway Float
, Bool -> Integer -> RoundTowardPositive Float
, Bool -> Integer -> RoundTowardZero Float
, Bool -> Integer -> Product RoundTowardNegative RoundTowardPositive Double
, Bool -> Integer -> Product RoundTowardNegative RoundTowardPositive Float
#-}
{-# RULES
"fromPositiveIntegerR/RoundTowardNegative"
fromPositiveIntegerR = \neg x -> RoundTowardNegative (roundTowardPositive (fromPositiveIntegerR (not neg) x))
#-}