lhc-0.8: lib/integer-native/src/GHC/Integer.hs
module GHC.Integer
( Integer
, toInt#
, eqInteger
, neqInteger
, ltInteger
, leInteger
, gtInteger
, geInteger
, compareInteger
, quotRemInteger
, plusInteger
, minusInteger
, timesInteger
, negateInteger
, absInteger
, signumInteger
, smallInteger
, quotInteger
, remInteger
, divModInteger
, lcmInteger
, gcdInteger
, andInteger
, orInteger
, xorInteger
, complementInteger
#if WORD_SIZE == 4
, integerToWord64
, integerToInt64
, word64ToInteger
, int64ToInteger
#endif
, wordToInteger
, integerToWord
, floatFromInteger
, doubleFromInteger
) where
import GHC.Types
import GHC.Prim
import GHC.Bool
import GHC.Ordering
import GHC.IntWord64
import GHC.Integer.Internals
toInt# :: Integer -> Int#
toInt# (Integer i) = i
eqInteger :: Integer -> Integer -> Bool
eqInteger (Integer a) (Integer b) = a ==# b
neqInteger :: Integer -> Integer -> Bool
neqInteger (Integer a) (Integer b) = a /=# b
ltInteger :: Integer -> Integer -> Bool
ltInteger (Integer a) (Integer b) = a <# b
leInteger :: Integer -> Integer -> Bool
leInteger (Integer a) (Integer b) = a <=# b
gtInteger :: Integer -> Integer -> Bool
gtInteger (Integer a) (Integer b) = a ># b
geInteger :: Integer -> Integer -> Bool
geInteger (Integer a) (Integer b) = a >=# b
compareInteger :: Integer -> Integer -> Ordering
compareInteger (Integer a) (Integer b)
= if a ># b
then GT
else if a ==# b
then EQ
else LT
quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
quotRemInteger (Integer a) (Integer b)
= (# Integer (a `quotInt#` b), Integer (a `remInt#` b) #)
plusInteger :: Integer -> Integer -> Integer
plusInteger (Integer a) (Integer b) = Integer (a +# b)
minusInteger :: Integer -> Integer -> Integer
minusInteger (Integer a) (Integer b) = Integer (a -# b)
timesInteger :: Integer -> Integer -> Integer
timesInteger (Integer a) (Integer b) = Integer (a *# b)
negateInteger :: Integer -> Integer
negateInteger (Integer a) = Integer (negateInt# a)
absInteger :: Integer -> Integer
absInteger (Integer n) = Integer (if n ># 0# then n else negateInt# n)
signumInteger :: Integer -> Integer
signumInteger (Integer i)
= if i <# 0#
then Integer (negateInt# 1#) else if i ==# 0#
then Integer 0#
else Integer 1#
smallInteger :: Int# -> Integer
smallInteger i
= Integer i
quotInteger :: Integer -> Integer -> Integer
quotInteger (Integer a) (Integer b)
= Integer (a `quotInt#` b)
remInteger :: Integer -> Integer -> Integer
remInteger (Integer a) (Integer b)
= Integer (a `remInt#` b)
divModInteger :: Integer -> Integer -> (# Integer, Integer #)
divModInteger (Integer a) (Integer b)
= (# Integer (a `divInt#` b), Integer (a `modInt#` b) #)
lcmInteger :: Integer -> Integer -> Integer
lcmInteger a b = a
gcdInteger :: Integer -> Integer -> Integer
gcdInteger (Integer a) (Integer b) = Integer (a `gcdInt#` b)
andInteger :: Integer -> Integer -> Integer
andInteger (Integer a) (Integer b)
= Integer (word2Int# (int2Word# a `and#` int2Word# b))
orInteger :: Integer -> Integer -> Integer
orInteger (Integer a) (Integer b)
= Integer (word2Int# (int2Word# a `or#` int2Word# b))
xorInteger :: Integer -> Integer -> Integer
xorInteger (Integer a) (Integer b)
= Integer (word2Int# (int2Word# a `xor#` int2Word# b))
complementInteger :: Integer -> Integer
complementInteger (Integer x#)
= Integer (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
#if WORD_SIZE == 4
integerToWord64 :: Integer -> Word64#
integerToWord64 (Integer x) = int64ToWord64# (intToInt64# x)
integerToInt64 :: Integer -> Int64#
integerToInt64 (Integer x) = intToInt64# x
word64ToInteger :: Word64# -> Integer
word64ToInteger w = Integer (int64ToInt# (word64ToInt64# w))
int64ToInteger :: Int64# -> Integer
int64ToInteger i = smallInteger (int64ToInt# i)
#endif
wordToInteger :: Word# -> Integer
wordToInteger w = Integer (word2Int# w)
integerToWord :: Integer -> Word#
integerToWord (Integer i) = int2Word# i
floatFromInteger :: Integer -> Float#
floatFromInteger (Integer i) = int2Float# i
doubleFromInteger :: Integer -> Double#
doubleFromInteger (Integer i) = int2Double# i
divInt# :: Int# -> Int# -> Int#
x# `divInt#` y#
-- Be careful NOT to overflow if we do any additional arithmetic
-- on the arguments... the following previous version of this
-- code has problems with overflow:
-- | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y#
-- | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y#
= if (x# ># 0#) && (y# <# 0#)
then ((x# -# 1#) `quotInt#` y#) -# 1#
else if (x# <# 0#) && (y# ># 0#)
then ((x# +# 1#) `quotInt#` y#) -# 1#
else x# `quotInt#` y#
modInt# :: Int# -> Int# -> Int#
x# `modInt#` y#
= if (x# ># 0#) && (y# <# 0#) ||
(x# <# 0#) && (y# ># 0#)
then if r# /=# 0# then r# +# y# else 0#
else r#
where
r# = x# `remInt#` y#
True && True = True
_ && _ = False
otherwise = True
False || False = False
_ || _ = True