ghc-bignum-1.0: src/GHC/Num/Natural.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BlockArguments #-}
#include "MachDeps.h"
#include "WordSize.h"
module GHC.Num.Natural where
import GHC.Prim
import GHC.Types
import GHC.Classes
import GHC.Num.BigNat
import GHC.Num.Primitives
default ()
-- | Natural number
--
-- Invariant: numbers <= WORD_MAXBOUND use the `NS` constructor
data Natural
= NS !Word#
| NB !BigNat#
instance Eq Natural where
(==) = naturalEq
(/=) = naturalNe
instance Ord Natural where
compare = naturalCompare
(>) = naturalGt
(>=) = naturalGe
(<) = naturalLt
(<=) = naturalLe
-- | Check Natural invariants
naturalCheck# :: Natural -> Bool#
naturalCheck# (NS _) = 1#
naturalCheck# (NB bn) = bigNatCheck# bn &&# bigNatSize# bn ># 1#
-- | Check Natural invariants
naturalCheck :: Natural -> Bool
naturalCheck !n = isTrue# (naturalCheck# n)
-- | Zero Natural
naturalZero :: Natural
naturalZero = NS 0##
-- | One Natural
naturalOne :: Natural
naturalOne = NS 1##
-- | Test Zero Natural
naturalIsZero :: Natural -> Bool
naturalIsZero (NS 0##) = True
naturalIsZero _ = False
-- | Test One Natural
naturalIsOne :: Natural -> Bool
naturalIsOne (NS 1##) = True
naturalIsOne _ = False
-- | Indicate if the value is a power of two and which one
naturalIsPowerOf2# :: Natural -> (# (# #) | Word# #)
naturalIsPowerOf2# (NS w) = wordIsPowerOf2# w
naturalIsPowerOf2# (NB w) = bigNatIsPowerOf2# w
-- | Create a Natural from a BigNat# (respect the invariants)
naturalFromBigNat# :: BigNat# -> Natural
naturalFromBigNat# x = case bigNatSize# x of
0# -> naturalZero
1# -> NS (bigNatIndex# x 0#)
_ -> NB x
-- | Convert a Natural into a BigNat#
naturalToBigNat# :: Natural -> BigNat#
naturalToBigNat# (NS w) = bigNatFromWord# w
naturalToBigNat# (NB bn) = bn
-- | Create a Natural from a Word#
naturalFromWord# :: Word# -> Natural
naturalFromWord# x = NS x
-- | Convert two Word# (most-significant first) into a Natural
naturalFromWord2# :: Word# -> Word# -> Natural
naturalFromWord2# 0## 0## = naturalZero
naturalFromWord2# 0## l = NS l
naturalFromWord2# h l = NB (bigNatFromWord2# h l)
-- | Create a Natural from a Word
naturalFromWord :: Word -> Natural
naturalFromWord (W# x) = NS x
-- | Create a Natural from a list of Word
naturalFromWordList :: [Word] -> Natural
naturalFromWordList xs = naturalFromBigNat# (bigNatFromWordList xs)
-- | Convert the lower bits of a Natural into a Word#
naturalToWord# :: Natural -> Word#
{-# NOINLINE naturalToWord# #-}
naturalToWord# (NS x) = x
naturalToWord# (NB b) = bigNatIndex# b 0#
-- | Convert the lower bits of a Natural into a Word
naturalToWord :: Natural -> Word
naturalToWord !n = W# (naturalToWord# n)
-- | Convert a Natural into a Word# clamping to (maxBound :: Word#).
naturalToWordClamp# :: Natural -> Word#
{-# NOINLINE naturalToWordClamp #-}
naturalToWordClamp# (NS x) = x
naturalToWordClamp# (NB _) = WORD_MAXBOUND##
-- | Convert a Natural into a Word# clamping to (maxBound :: Word).
naturalToWordClamp :: Natural -> Word
naturalToWordClamp !n = W# (naturalToWordClamp# n)
-- | Try downcasting 'Natural' to 'Word' value.
-- Returns '(##)' if value doesn't fit in 'Word'.
naturalToWordMaybe# :: Natural -> (# (# #) | Word# #)
naturalToWordMaybe# (NS w) = (# | w #)
naturalToWordMaybe# _ = (# (# #) | #)
-- | Encode (# Natural mantissa, Int# exponent #) into a Double#
naturalEncodeDouble# :: Natural -> Int# -> Double#
naturalEncodeDouble# (NS w) 0# = word2Double# w
naturalEncodeDouble# (NS w) e = wordEncodeDouble# w e
naturalEncodeDouble# (NB b) e = bigNatEncodeDouble# b e
-- | Encode a Natural (mantissa) into a Double#
naturalToDouble# :: Natural -> Double#
naturalToDouble# !n = naturalEncodeDouble# n 0#
-- | Encode a Natural (mantissa) into a Float#
naturalToFloat# :: Natural -> Float#
naturalToFloat# !i = naturalEncodeFloat# i 0#
-- | Encode (# Natural mantissa, Int# exponent #) into a Float#
--
-- TODO: Not sure if it's worth to write 'Float' optimized versions here
naturalEncodeFloat# :: Natural -> Int# -> Float#
naturalEncodeFloat# !m 0# = double2Float# (naturalToDouble# m)
naturalEncodeFloat# !m e = double2Float# (naturalEncodeDouble# m e)
-- | Equality test for Natural
naturalEq# :: Natural -> Natural -> Bool#
{-# NOINLINE naturalEq# #-}
naturalEq# (NS x) (NS y) = x `eqWord#` y
naturalEq# (NB x) (NB y) = bigNatEq# x y
naturalEq# _ _ = 0#
-- | Equality test for Natural
naturalEq :: Natural -> Natural -> Bool
naturalEq !x !y = isTrue# (naturalEq# x y)
-- | Inequality test for Natural
naturalNe# :: Natural -> Natural -> Bool#
{-# NOINLINE naturalNe# #-}
naturalNe# (NS x) (NS y) = x `neWord#` y
naturalNe# (NB x) (NB y) = bigNatNe# x y
naturalNe# _ _ = 1#
-- | Inequality test for Natural
naturalNe :: Natural -> Natural -> Bool
naturalNe !x !y = isTrue# (naturalNe# x y)
-- | Greater or equal test for Natural
naturalGe# :: Natural -> Natural -> Bool#
{-# NOINLINE naturalGe# #-}
naturalGe# (NS x) (NS y) = x `geWord#` y
naturalGe# (NS _) (NB _) = 0#
naturalGe# (NB _) (NS _) = 1#
naturalGe# (NB x) (NB y) = bigNatGe# x y
-- | Greater or equal test for Natural
naturalGe :: Natural -> Natural -> Bool
naturalGe !x !y = isTrue# (naturalGe# x y)
-- | Lower or equal test for Natural
naturalLe# :: Natural -> Natural -> Bool#
{-# NOINLINE naturalLe# #-}
naturalLe# (NS x) (NS y) = x `leWord#` y
naturalLe# (NS _) (NB _) = 1#
naturalLe# (NB _) (NS _) = 0#
naturalLe# (NB x) (NB y) = bigNatLe# x y
-- | Lower or equal test for Natural
naturalLe :: Natural -> Natural -> Bool
naturalLe !x !y = isTrue# (naturalLe# x y)
-- | Greater test for Natural
naturalGt# :: Natural -> Natural -> Bool#
{-# NOINLINE naturalGt# #-}
naturalGt# (NS x) (NS y) = x `gtWord#` y
naturalGt# (NS _) (NB _) = 0#
naturalGt# (NB _) (NS _) = 1#
naturalGt# (NB x) (NB y) = bigNatGt# x y
-- | Greater test for Natural
naturalGt :: Natural -> Natural -> Bool
naturalGt !x !y = isTrue# (naturalGt# x y)
-- | Lower test for Natural
naturalLt# :: Natural -> Natural -> Bool#
{-# NOINLINE naturalLt# #-}
naturalLt# (NS x) (NS y) = x `ltWord#` y
naturalLt# (NS _) (NB _) = 1#
naturalLt# (NB _) (NS _) = 0#
naturalLt# (NB x) (NB y) = bigNatLt# x y
-- | Lower test for Natural
naturalLt :: Natural -> Natural -> Bool
naturalLt !x !y = isTrue# (naturalLt# x y)
-- | Compare two Natural
naturalCompare :: Natural -> Natural -> Ordering
{-# NOINLINE naturalCompare #-}
naturalCompare (NS x) (NS y) = cmpW# x y
naturalCompare (NB x) (NB y) = bigNatCompare x y
naturalCompare (NS _) (NB _) = LT
naturalCompare (NB _) (NS _) = GT
-- | PopCount for Natural
naturalPopCount# :: Natural -> Word#
{-# NOINLINE naturalPopCount# #-}
naturalPopCount# (NS x) = popCnt# x
naturalPopCount# (NB x) = bigNatPopCount# x
-- | PopCount for Natural
naturalPopCount :: Natural -> Word
naturalPopCount (NS x) = W# (popCnt# x)
naturalPopCount (NB x) = bigNatPopCount x
-- | Right shift for Natural
naturalShiftR# :: Natural -> Word# -> Natural
{-# NOINLINE naturalShiftR# #-}
naturalShiftR# (NS x) n = NS (x `shiftRW#` n)
naturalShiftR# (NB x) n = naturalFromBigNat# (x `bigNatShiftR#` n)
-- | Right shift for Natural
naturalShiftR :: Natural -> Word -> Natural
naturalShiftR x (W# n) = naturalShiftR# x n
-- | Left shift
naturalShiftL# :: Natural -> Word# -> Natural
{-# NOINLINE naturalShiftL# #-}
naturalShiftL# v@(NS x) n
| 0## <- x = v
| isTrue# (clz# x `geWord#` n) = NS (x `uncheckedShiftL#` word2Int# n)
| True = NB (bigNatFromWord# x `bigNatShiftL#` n)
naturalShiftL# (NB x) n = NB (x `bigNatShiftL#` n)
-- | Left shift
naturalShiftL :: Natural -> Word -> Natural
naturalShiftL !x (W# n) = naturalShiftL# x n
-- | Add two naturals
naturalAdd :: Natural -> Natural -> Natural
{-# NOINLINE naturalAdd #-}
naturalAdd (NS x) (NB y) = NB (bigNatAddWord# y x)
naturalAdd (NB x) (NS y) = NB (bigNatAddWord# x y)
naturalAdd (NB x) (NB y) = NB (bigNatAdd x y)
naturalAdd (NS x) (NS y) =
case addWordC# x y of
(# l,0# #) -> NS l
(# l,c #) -> NB (bigNatFromWord2# (int2Word# c) l)
-- | Sub two naturals
naturalSub :: Natural -> Natural -> (# Void# | Natural #)
{-# NOINLINE naturalSub #-}
naturalSub (NS _) (NB _) = (# void# | #)
naturalSub (NB x) (NS y) = (# | naturalFromBigNat# (bigNatSubWordUnsafe# x y) #)
naturalSub (NS x) (NS y) =
case subWordC# x y of
(# l,0# #) -> (# | NS l #)
(# _,_ #) -> (# void# | #)
naturalSub (NB x) (NB y) =
case bigNatSub x y of
(# (# #) | #) -> (# void# | #)
(# | z #) -> (# | naturalFromBigNat# z #)
-- | Sub two naturals
--
-- Throw an Underflow exception if x < y
naturalSubThrow :: Natural -> Natural -> Natural
{-# NOINLINE naturalSubThrow #-}
naturalSubThrow (NS _) (NB _) = raiseUnderflow
naturalSubThrow (NB x) (NS y) = naturalFromBigNat# (bigNatSubWordUnsafe# x y)
naturalSubThrow (NS x) (NS y) =
case subWordC# x y of
(# l,0# #) -> NS l
(# _,_ #) -> raiseUnderflow
naturalSubThrow (NB x) (NB y) =
case bigNatSub x y of
(# (# #) | #) -> raiseUnderflow
(# | z #) -> naturalFromBigNat# z
-- | Sub two naturals
--
-- Unsafe: don't check that x >= y
-- Undefined results if it happens
naturalSubUnsafe :: Natural -> Natural -> Natural
{-# NOINLINE naturalSubUnsafe #-}
naturalSubUnsafe (NS x) (NS y) = NS (minusWord# x y)
naturalSubUnsafe (NS _) (NB _) = naturalZero
naturalSubUnsafe (NB x) (NS y) = naturalFromBigNat# (bigNatSubWordUnsafe# x y)
naturalSubUnsafe (NB x) (NB y) =
case bigNatSub x y of
(# (# #) | #) -> naturalZero
(# | z #) -> naturalFromBigNat# z
-- | Multiplication
naturalMul :: Natural -> Natural -> Natural
{-# NOINLINE naturalMul #-}
naturalMul a b = case a of
NS 0## -> NS 0##
NS 1## -> b
NS x -> case b of
NS 0## -> NS 0##
NS 1## -> a
NS y -> case timesWord2# x y of
(# h,l #) -> naturalFromWord2# h l
NB y -> NB (bigNatMulWord# y x)
NB x -> case b of
NS 0## -> NS 0##
NS 1## -> a
NS y -> NB (bigNatMulWord# x y)
NB y -> NB (bigNatMul x y)
-- | Square a Natural
naturalSqr :: Natural -> Natural
naturalSqr !a = naturalMul a a
-- | Signum for Natural
naturalSignum :: Natural -> Natural
{-# NOINLINE naturalSignum #-}
naturalSignum (NS 0##) = NS 0##
naturalSignum _ = NS 1##
-- | Negate for Natural
naturalNegate :: Natural -> Natural
{-# NOINLINE naturalNegate #-}
naturalNegate (NS 0##) = NS 0##
naturalNegate _ = raiseUnderflow
-- | Return division quotient and remainder
--
-- Division by zero is handled by BigNat
naturalQuotRem# :: Natural -> Natural -> (# Natural, Natural #)
{-# NOINLINE naturalQuotRem# #-}
naturalQuotRem# (NS n) (NS d) = case quotRemWord# n d of
(# q, r #) -> (# NS q, NS r #)
naturalQuotRem# (NB n) (NS d) = case bigNatQuotRemWord# n d of
(# q, r #) -> (# naturalFromBigNat# q, NS r #)
naturalQuotRem# (NS n) (NB d) = case bigNatQuotRem# (bigNatFromWord# n) d of
(# q, r #) -> (# naturalFromBigNat# q, naturalFromBigNat# r #)
naturalQuotRem# (NB n) (NB d) = case bigNatQuotRem# n d of
(# q, r #) -> (# naturalFromBigNat# q, naturalFromBigNat# r #)
-- | Return division quotient and remainder
naturalQuotRem :: Natural -> Natural -> (Natural, Natural)
naturalQuotRem !n !d = case naturalQuotRem# n d of
(# q, r #) -> (q,r)
-- | Return division quotient
naturalQuot :: Natural -> Natural -> Natural
{-# NOINLINE naturalQuot #-}
naturalQuot (NS n) (NS d) = case quotWord# n d of
q -> NS q
naturalQuot (NB n) (NS d) = case bigNatQuotWord# n d of
q -> naturalFromBigNat# q
naturalQuot (NS n) (NB d) = case bigNatQuot (bigNatFromWord# n) d of
q -> naturalFromBigNat# q
naturalQuot (NB n) (NB d) = case bigNatQuot n d of
q -> naturalFromBigNat# q
-- | Return division remainder
naturalRem :: Natural -> Natural -> Natural
{-# NOINLINE naturalRem #-}
naturalRem (NS n) (NS d) = case remWord# n d of
r -> NS r
naturalRem (NB n) (NS d) = case bigNatRemWord# n d of
r -> NS r
naturalRem (NS n) (NB d) = case bigNatRem (bigNatFromWord# n) d of
r -> naturalFromBigNat# r
naturalRem (NB n) (NB d) = case bigNatRem n d of
r -> naturalFromBigNat# r
naturalAnd :: Natural -> Natural -> Natural
{-# NOINLINE naturalAnd #-}
naturalAnd (NS n) (NS m) = NS (n `and#` m)
naturalAnd (NS n) (NB m) = NS (n `and#` bigNatToWord# m)
naturalAnd (NB n) (NS m) = NS (bigNatToWord# n `and#` m)
naturalAnd (NB n) (NB m) = naturalFromBigNat# (bigNatAnd n m)
naturalAndNot :: Natural -> Natural -> Natural
{-# NOINLINE naturalAndNot #-}
naturalAndNot (NS n) (NS m) = NS (n `and#` not# m)
naturalAndNot (NS n) (NB m) = NS (n `and#` not# (bigNatToWord# m))
naturalAndNot (NB n) (NS m) = NS (bigNatToWord# n `and#` not# m)
naturalAndNot (NB n) (NB m) = naturalFromBigNat# (bigNatAndNot n m)
naturalOr :: Natural -> Natural -> Natural
{-# NOINLINE naturalOr #-}
naturalOr (NS n) (NS m) = NS (n `or#` m)
naturalOr (NS n) (NB m) = NB (bigNatOrWord# m n)
naturalOr (NB n) (NS m) = NB (bigNatOrWord# n m)
naturalOr (NB n) (NB m) = NB (bigNatOr n m)
naturalXor :: Natural -> Natural -> Natural
{-# NOINLINE naturalXor #-}
naturalXor (NS n) (NS m) = NS (n `xor#` m)
naturalXor (NS n) (NB m) = NB (bigNatXorWord# m n)
naturalXor (NB n) (NS m) = NB (bigNatXorWord# n m)
naturalXor (NB n) (NB m) = naturalFromBigNat# (bigNatXor n m)
naturalTestBit# :: Natural -> Word# -> Bool#
{-# NOINLINE naturalTestBit# #-}
naturalTestBit# (NS w) i = (i `ltWord#` WORD_SIZE_IN_BITS##) &&#
((w `and#` (1## `uncheckedShiftL#` word2Int# i)) `neWord#` 0##)
naturalTestBit# (NB bn) i = bigNatTestBit# bn i
naturalTestBit :: Natural -> Word -> Bool
naturalTestBit !n (W# i) = isTrue# (naturalTestBit# n i)
naturalBit# :: Word# -> Natural
{-# NOINLINE naturalBit# #-}
naturalBit# i
| isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##) = NS (1## `uncheckedShiftL#` word2Int# i)
| True = NB (bigNatBit# i)
naturalBit :: Word -> Natural
naturalBit (W# i) = naturalBit# i
-- | Compute greatest common divisor.
naturalGcd :: Natural -> Natural -> Natural
{-# NOINLINE naturalGcd #-}
naturalGcd (NS 0##) !y = y
naturalGcd x (NS 0##) = x
naturalGcd (NS 1##) _ = NS 1##
naturalGcd _ (NS 1##) = NS 1##
naturalGcd (NB x) (NB y) = naturalFromBigNat# (bigNatGcd x y)
naturalGcd (NB x) (NS y) = NS (bigNatGcdWord# x y)
naturalGcd (NS x) (NB y) = NS (bigNatGcdWord# y x)
naturalGcd (NS x) (NS y) = NS (gcdWord# x y)
-- | Compute least common multiple.
naturalLcm :: Natural -> Natural -> Natural
{-# NOINLINE naturalLcm #-}
naturalLcm (NS 0##) !_ = NS 0##
naturalLcm _ (NS 0##) = NS 0##
naturalLcm (NS 1##) y = y
naturalLcm x (NS 1##) = x
naturalLcm (NS a ) (NS b ) = naturalFromBigNat# (bigNatLcmWordWord# a b)
naturalLcm (NB a ) (NS b ) = naturalFromBigNat# (bigNatLcmWord# a b)
naturalLcm (NS a ) (NB b ) = naturalFromBigNat# (bigNatLcmWord# b a)
naturalLcm (NB a ) (NB b ) = naturalFromBigNat# (bigNatLcm a b)
-- | Base 2 logarithm
naturalLog2# :: Natural -> Word#
{-# NOINLINE naturalLog2# #-}
naturalLog2# (NS w) = wordLog2# w
naturalLog2# (NB b) = bigNatLog2# b
-- | Base 2 logarithm
naturalLog2 :: Natural -> Word
naturalLog2 !n = W# (naturalLog2# n)
-- | Logarithm for an arbitrary base
naturalLogBaseWord# :: Word# -> Natural -> Word#
{-# NOINLINE naturalLogBaseWord# #-}
naturalLogBaseWord# base (NS a) = wordLogBase# base a
naturalLogBaseWord# base (NB a) = bigNatLogBaseWord# base a
-- | Logarithm for an arbitrary base
naturalLogBaseWord :: Word -> Natural -> Word
naturalLogBaseWord (W# base) !a = W# (naturalLogBaseWord# base a)
-- | Logarithm for an arbitrary base
naturalLogBase# :: Natural -> Natural -> Word#
{-# NOINLINE naturalLogBase# #-}
naturalLogBase# (NS base) !a = naturalLogBaseWord# base a
naturalLogBase# (NB _ ) (NS _) = 0##
naturalLogBase# (NB base) (NB a) = bigNatLogBase# base a
-- | Logarithm for an arbitrary base
naturalLogBase :: Natural -> Natural -> Word
naturalLogBase !base !a = W# (naturalLogBase# base a)
-- | \"@'naturalPowMod' /b/ /e/ /m/@\" computes base @/b/@ raised to
-- exponent @/e/@ modulo @/m/@.
naturalPowMod :: Natural -> Natural -> Natural -> Natural
{-# NOINLINE naturalPowMod #-}
naturalPowMod !_ !_ (NS 0##) = raiseDivZero
naturalPowMod _ _ (NS 1##) = NS 0##
naturalPowMod _ (NS 0##) _ = NS 1##
naturalPowMod (NS 0##) _ _ = NS 0##
naturalPowMod (NS 1##) _ _ = NS 1##
naturalPowMod (NS b) (NS e) (NS m) = NS (powModWord# b e m)
naturalPowMod b e (NS m) = NS (bigNatPowModWord#
(naturalToBigNat# b)
(naturalToBigNat# e)
m)
naturalPowMod b e (NB m) = naturalFromBigNat#
(bigNatPowMod (naturalToBigNat# b)
(naturalToBigNat# e)
m)
-- | Compute the number of digits of the Natural in the given base.
--
-- `base` must be > 1
naturalSizeInBase# :: Word# -> Natural -> Word#
{-# NOINLINE naturalSizeInBase# #-}
naturalSizeInBase# base (NS w) = wordSizeInBase# base w
naturalSizeInBase# base (NB n) = bigNatSizeInBase# base n
-- | Write a 'Natural' to @/addr/@ in base-256 representation and return the
-- number of bytes written.
--
-- The endianness is selected with the Bool# parameter: write most significant
-- byte first (big-endian) if @1#@ or least significant byte first
-- (little-endian) if @0#@.
naturalToAddr# :: Natural -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
{-# NOINLINE naturalToAddr# #-}
naturalToAddr# (NS i) = wordToAddr# i
naturalToAddr# (NB n) = bigNatToAddr# n
-- | Write a 'Natural' to @/addr/@ in base-256 representation and return the
-- number of bytes written.
--
-- The endianness is selected with the Bool# parameter: write most significant
-- byte first (big-endian) if @1#@ or least significant byte first
-- (little-endian) if @0#@.
naturalToAddr :: Natural -> Addr# -> Bool# -> IO Word
naturalToAddr a addr e = IO \s -> case naturalToAddr# a addr e s of
(# s', w #) -> (# s', W# w #)
-- | Read a Natural in base-256 representation from an Addr#.
--
-- The size is given in bytes.
--
-- The endianness is selected with the Bool# parameter: most significant
-- byte first (big-endian) if @1#@ or least significant byte first
-- (little-endian) if @0#@.
--
-- Null higher limbs are automatically trimed.
naturalFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Natural #)
{-# NOINLINE naturalFromAddr# #-}
naturalFromAddr# sz addr e s =
case bigNatFromAddr# sz addr e s of
(# s', n #) -> (# s', naturalFromBigNat# n #)
-- | Read a Natural in base-256 representation from an Addr#.
--
-- The size is given in bytes.
--
-- The endianness is selected with the Bool# parameter: most significant
-- byte first (big-endian) if @1#@ or least significant byte first
-- (little-endian) if @0#@.
--
-- Null higher limbs are automatically trimed.
naturalFromAddr :: Word# -> Addr# -> Bool# -> IO Natural
naturalFromAddr sz addr e = IO (naturalFromAddr# sz addr e)
-- | Write a Natural in base-256 representation and return the
-- number of bytes written.
--
-- The endianness is selected with the Bool# parameter: most significant
-- byte first (big-endian) if @1#@ or least significant byte first
-- (little-endian) if @0#@.
naturalToMutableByteArray# :: Natural -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
{-# NOINLINE naturalToMutableByteArray# #-}
naturalToMutableByteArray# (NS w) = wordToMutableByteArray# w
naturalToMutableByteArray# (NB a) = bigNatToMutableByteArray# a
-- | Read a Natural in base-256 representation from a ByteArray#.
--
-- The size is given in bytes.
--
-- The endianness is selected with the Bool# parameter: most significant
-- byte first (big-endian) if @1#@ or least significant byte first
-- (little-endian) if @0#@.
--
-- Null higher limbs are automatically trimed.
naturalFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> State# s -> (# State# s, Natural #)
{-# NOINLINE naturalFromByteArray# #-}
naturalFromByteArray# sz ba off e s = case bigNatFromByteArray# sz ba off e s of
(# s', a #) -> (# s', naturalFromBigNat# a #)