Commit 995e8c1c authored by Herbert Valerio Riedel's avatar Herbert Valerio Riedel 🕺

Drop old integer-gmp-0.5 from GHC source tree

This completes what c774b28f (#9281)
started.  `integer-gmp-1.0` was added as an additional
`libraries/integer-gmp2` folder while retaining the ability to configure
GHC w/ the old `integer-gmp-0.5` to have a way back, and or the ability
to easily switch between old/new `integer-gmp` for benchmark/debugging
purposes.

This commit removes the old `libraries/integer-gmp` folder and moves
`libraries/integer-gmp2` into its place, while removing any mentions of
"gmp2" as well as the to support two different `integer-gmp` packages in
GHC's source-tree.

Reviewed By: austin

Differential Revision: https://phabricator.haskell.org/D769
parent 1f69f37f
......@@ -383,7 +383,6 @@ integerPackageKey = fsToPackageKey (fsLit n)
where
n = case cIntegerLibraryType of
IntegerGMP -> "integer-gmp"
IntegerGMP2 -> "integer-gmp"
IntegerSimple -> "integer-simple"
basePackageKey = fsToPackageKey (fsLit "base")
rtsPackageKey = fsToPackageKey (fsLit "rts")
......
......@@ -1159,8 +1159,6 @@ lookupIntegerSDataConName :: DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupIntegerSDataConName dflags hsc_env = case cIntegerLibraryType of
IntegerGMP -> guardIntegerUse dflags $ liftM Just $
initTcForLookup hsc_env (tcLookupDataCon integerSDataConName)
IntegerGMP2-> guardIntegerUse dflags $ liftM Just $
initTcForLookup hsc_env (tcLookupDataCon integerSDataConName)
IntegerSimple -> return Nothing
-- | Helper for 'lookupMkIntegerName' and 'lookupIntegerSDataConName'
......
......@@ -54,7 +54,6 @@ compiler/stage%/build/Config.hs : mk/config.mk mk/project.mk | $$(dir $$@)/.
@echo '#include "ghc_boot_platform.h"' >> $@
@echo >> $@
@echo 'data IntegerLibrary = IntegerGMP' >> $@
@echo ' | IntegerGMP2' >> $@
@echo ' | IntegerSimple' >> $@
@echo ' deriving Eq' >> $@
@echo >> $@
......@@ -88,8 +87,6 @@ compiler/stage%/build/Config.hs : mk/config.mk mk/project.mk | $$(dir $$@)/.
@echo 'cIntegerLibraryType :: IntegerLibrary' >> $@
ifeq "$(INTEGER_LIBRARY)" "integer-gmp"
@echo 'cIntegerLibraryType = IntegerGMP' >> $@
else ifeq "$(INTEGER_LIBRARY)" "integer-gmp2"
@echo 'cIntegerLibraryType = IntegerGMP2' >> $@
else ifeq "$(INTEGER_LIBRARY)" "integer-simple"
@echo 'cIntegerLibraryType = IntegerSimple' >> $@
else ifneq "$(CLEANING)" "YES"
......
......@@ -371,7 +371,6 @@ basicKnownKeyNames
] ++ case cIntegerLibraryType of
IntegerGMP -> [integerSDataConName]
IntegerGMP2 -> [integerSDataConName]
IntegerSimple -> []
genericTyConNames :: [Name]
......@@ -964,7 +963,6 @@ integerTyConName = tcQual gHC_INTEGER_TYPE (fsLit "Integer") int
integerSDataConName = conName gHC_INTEGER_TYPE (fsLit n) integerSDataConKey
where n = case cIntegerLibraryType of
IntegerGMP -> "S#"
IntegerGMP2 -> "S#"
IntegerSimple -> panic "integerSDataConName evaluated for integer-simple"
mkIntegerName = varQual gHC_INTEGER_TYPE (fsLit "mkInteger") mkIntegerIdKey
integerToWord64Name = varQual gHC_INTEGER_TYPE (fsLit "integerToWord64") integerToWord64IdKey
......
......@@ -587,8 +587,6 @@ libraries/ghc-prim_dist-install_EXTRA_HADDOCK_SRCS = libraries/ghc-prim/dist-ins
ifneq "$(CLEANING)" "YES"
ifeq "$(INTEGER_LIBRARY)" "integer-gmp"
libraries/base_dist-install_CONFIGURE_OPTS += --flags=integer-gmp
else ifeq "$(INTEGER_LIBRARY)" "integer-gmp2"
libraries/base_dist-install_CONFIGURE_OPTS += --flags=integer-gmp2
else ifeq "$(INTEGER_LIBRARY)" "integer-simple"
libraries/base_dist-install_CONFIGURE_OPTS += --flags=integer-simple
else
......@@ -649,16 +647,8 @@ endif
ifeq "$(INTEGER_LIBRARY)" "integer-gmp"
BUILD_DIRS += libraries/integer-gmp/gmp
BUILD_DIRS += libraries/integer-gmp/mkGmpDerivedConstants
else ifneq "$(findstring clean,$(MAKECMDGOALS))" ""
BUILD_DIRS += libraries/integer-gmp/gmp
BUILD_DIRS += libraries/integer-gmp/mkGmpDerivedConstants
endif
ifeq "$(INTEGER_LIBRARY)" "integer-gmp2"
BUILD_DIRS += libraries/integer-gmp2/gmp
else ifneq "$(findstring clean,$(MAKECMDGOALS))" ""
BUILD_DIRS += libraries/integer-gmp2/gmp
endif
ifeq "$(HADDOCK_DOCS)" "YES"
......@@ -1233,9 +1223,7 @@ sdist_%:
.PHONY: clean
CLEAN_FILES += libraries/integer-gmp/cbits/GmpDerivedConstants.h
CLEAN_FILES += libraries/integer-gmp/include/HsIntegerGmp.h
CLEAN_FILES += libraries/integer-gmp2/include/HsIntegerGmp.h
CLEAN_FILES += libraries/base/include/EventConfig.h
CLEAN_FILES += mk/config.mk.old
CLEAN_FILES += mk/project.mk.old
......
......@@ -52,11 +52,6 @@ Flag integer-gmp
Manual: True
Default: False
Flag integer-gmp2
Description: Use integer-gmp2
Manual: True
Default: False
Library
default-language: Haskell2010
other-extensions:
......@@ -103,10 +98,6 @@ Library
build-depends: integer-simple >= 0.1.1 && < 0.2
if flag(integer-gmp)
build-depends: integer-gmp >= 0.5.1 && < 0.6
cpp-options: -DOPTIMISE_INTEGER_GCD_LCM
if flag(integer-gmp2)
build-depends: integer-gmp >= 1.0 && < 1.1
cpp-options: -DOPTIMISE_INTEGER_GCD_LCM
......
/GNUmakefile
/autom4te.cache/
/cbits/GmpDerivedConstants.h
/cbits/mkGmpDerivedConstants
/config.log
/config.status
/configure
/dist-install/
/ghc.mk
/gmp/config.mk
/GNUmakefile
/include/HsIntegerGmp.h
/integer-gmp.buildinfo
/mkGmpDerivedConstants/dist/
/gmp/gmp.h
/gmp/gmpbuild
/include/ghc-gmp.h
\begin{code}
{-# LANGUAGE CPP, MagicHash, NoImplicitPrelude #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.Integer
-- Copyright : (c) The University of Glasgow 1994-2008
-- License : see libraries/integer-gmp/LICENSE
--
-- Maintainer : cvs-ghc@haskell.org
-- Stability : internal
-- Portability : non-portable (GHC Extensions)
--
-- The 'Integer' type.
--
-- This module exposes the /portable/ 'Integer' API. See
-- "GHC.Integer.GMP.Internals" for the GMP-specific internal
-- representation of 'Integer' as well as optimized GMP-specific
-- operations.
-----------------------------------------------------------------------------
#include "MachDeps.h"
module GHC.Integer (
Integer,
-- * Construct 'Integer's
mkInteger, smallInteger, wordToInteger,
#if WORD_SIZE_IN_BITS < 64
word64ToInteger, int64ToInteger,
#endif
-- * Conversion to other integral types
integerToWord, integerToInt,
#if WORD_SIZE_IN_BITS < 64
integerToWord64, integerToInt64,
#endif
-- * Helpers for 'RealFloat' type-class operations
encodeFloatInteger, floatFromInteger,
encodeDoubleInteger, decodeDoubleInteger, doubleFromInteger,
-- * Arithmetic operations
plusInteger, minusInteger, timesInteger, negateInteger,
absInteger, signumInteger,
divModInteger, divInteger, modInteger,
quotRemInteger, quotInteger, remInteger,
-- * Comparison predicates
eqInteger, neqInteger,
leInteger, gtInteger, ltInteger, geInteger, compareInteger,
eqInteger#, neqInteger#,
leInteger#, gtInteger#, ltInteger#, geInteger#,
-- * Bit-operations
andInteger, orInteger, xorInteger, complementInteger,
shiftLInteger, shiftRInteger, testBitInteger,
-- * Hashing
hashInteger,
) where
import GHC.Integer.Type
default ()
\end{code}
{-# LANGUAGE NoImplicitPrelude #-}
-- | This modules provides access to the 'Integer' constructors and
-- exposes some highly optimized GMP-operations.
--
-- Note that since @integer-gmp@ does not depend on `base`, error
-- reporting via exceptions, 'error', or 'undefined' is not
-- available. Instead, the low-level functions will crash the runtime
-- if called with invalid arguments.
--
-- See also
-- <https://ghc.haskell.org/trac/ghc/wiki/Commentary/Libraries/Integer GHC Commentary: Libraries/Integer>.
module GHC.Integer.GMP.Internals
( -- * The 'Integer' type
Integer(..)
-- * Number theoretic functions
, gcdInt
, gcdInteger
, gcdExtInteger
, lcmInteger
, nextPrimeInteger
, testPrimeInteger
-- * Exponentiation functions
, powInteger
, powModInteger
, powModSecInteger
, recipModInteger
-- * Import/export functions
, sizeInBaseInteger
, importIntegerFromByteArray
, importIntegerFromAddr
, exportIntegerToMutableByteArray
, exportIntegerToAddr
) where
import GHC.Integer.Type
{-# LANGUAGE BangPatterns, CPP, MagicHash, NoImplicitPrelude, UnboxedTuples
, UnliftedFFITypes, GHCForeignImportPrim #-}
{-# OPTIONS_HADDOCK hide #-}
#include "MachDeps.h"
module GHC.Integer.GMP.Prim (
MPZ#,
cmpInteger#,
cmpIntegerInt#,
plusInteger#,
plusIntegerInt#,
minusInteger#,
minusIntegerInt#,
timesInteger#,
timesIntegerInt#,
quotRemInteger#,
quotRemIntegerWord#,
quotInteger#,
quotIntegerWord#,
remInteger#,
remIntegerWord#,
divModInteger#,
divModIntegerWord#,
divInteger#,
divIntegerWord#,
modInteger#,
modIntegerWord#,
divExactInteger#,
divExactIntegerWord#,
gcdInteger#,
gcdExtInteger#,
gcdIntegerInt#,
gcdInt#,
decodeDouble#,
int2Integer#,
integer2Int#,
word2Integer#,
integer2Word#,
andInteger#,
orInteger#,
xorInteger#,
complementInteger#,
testBitInteger#,
mul2ExpInteger#,
fdivQ2ExpInteger#,
powInteger#,
powModInteger#,
powModSecInteger#,
recipModInteger#,
nextPrimeInteger#,
testPrimeInteger#,
sizeInBaseInteger#,
importIntegerFromByteArray#,
importIntegerFromAddr#,
exportIntegerToMutableByteArray#,
exportIntegerToAddr#,
#if WORD_SIZE_IN_BITS < 64
int64ToInteger#, integerToInt64#,
word64ToInteger#, integerToWord64#,
#endif
#ifndef WORD_SIZE_IN_BITS
#error WORD_SIZE_IN_BITS not defined!!!
#endif
) where
import GHC.Prim
import GHC.Types
-- Double isn't available yet, and we shouldn't be using defaults anyway:
default ()
-- | This is represents a @mpz_t@ value in a heap-saving way.
--
-- The first tuple element, @/s/@, encodes the sign of the integer
-- @/i/@ (i.e. @signum /s/ == signum /i/@), and the number of /limbs/
-- used to represent the magnitude. If @abs /s/ > 1@, the 'ByteArray#'
-- contains @abs /s/@ limbs encoding the integer. Otherwise, if @abs
-- /s/ < 2@, the single limb is stored in the 'Word#' element instead
-- (and the 'ByteArray#' element is undefined and MUST NOT be accessed
-- as it doesn't point to a proper 'ByteArray#' but rather to an
-- unsafe-coerced 'Int' in order be polite to the GC -- see
-- @DUMMY_BYTE_ARR@ in gmp-wrappers.cmm)
--
-- More specifically, the following encoding is used (where `⊥` means
-- undefined/unused):
--
-- * (# 0#, ⊥, 0## #) -> value = 0
-- * (# 1#, ⊥, w #) -> value = w
-- * (# -1#, ⊥, w #) -> value = -w
-- * (# s#, d, 0## #) -> value = J# s d
--
-- This representation allows to avoid temporary heap allocations
-- (-> Trac #8647) of 1-limb 'ByteArray#'s which fit into the
-- 'S#'-constructor. Moreover, this allows to delays 1-limb
-- 'ByteArray#' heap allocations, as such 1-limb `mpz_t`s can be
-- optimistically allocated on the Cmm stack and returned as a @#word@
-- in case the `mpz_t` wasn't grown beyond 1 limb by the GMP
-- operation.
--
-- See also the 'GHC.Integer.Type.mpzToInteger' function which ought
-- to be used for converting 'MPZ#'s to 'Integer's and the
-- @MP_INT_1LIMB_RETURN()@ macro in @gmp-wrappers.cmm@ which
-- constructs 'MPZ#' values in the first place for implementation
-- details.
type MPZ# = (# Int#, ByteArray#, Word# #)
-- | Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument.
--
foreign import prim "integer_cmm_cmpIntegerzh" cmpInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> Int#
-- | Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument, which
-- is an ordinary Int\#.
foreign import prim "integer_cmm_cmpIntegerIntzh" cmpIntegerInt#
:: Int# -> ByteArray# -> Int# -> Int#
-- |
--
foreign import prim "integer_cmm_plusIntegerzh" plusInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- | Optimized version of 'plusInteger#' for summing big-ints with small-ints
--
foreign import prim "integer_cmm_plusIntegerIntzh" plusIntegerInt#
:: Int# -> ByteArray# -> Int# -> MPZ#
-- |
--
foreign import prim "integer_cmm_minusIntegerzh" minusInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- | Optimized version of 'minusInteger#' for substracting small-ints from big-ints
--
foreign import prim "integer_cmm_minusIntegerIntzh" minusIntegerInt#
:: Int# -> ByteArray# -> Int# -> MPZ#
-- |
--
foreign import prim "integer_cmm_timesIntegerzh" timesInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- | Optimized version of 'timesInteger#' for multiplying big-ints with small-ints
--
foreign import prim "integer_cmm_timesIntegerIntzh" timesIntegerInt#
:: Int# -> ByteArray# -> Int# -> MPZ#
-- | Compute div and mod simultaneously, where div rounds towards negative
-- infinity and\ @(q,r) = divModInteger#(x,y)@ implies
-- @plusInteger# (timesInteger# q y) r = x@.
--
foreign import prim "integer_cmm_quotRemIntegerzh" quotRemInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> (# MPZ#, MPZ# #)
-- | Variant of 'quotRemInteger#'
--
foreign import prim "integer_cmm_quotRemIntegerWordzh" quotRemIntegerWord#
:: Int# -> ByteArray# -> Word# -> (# MPZ#, MPZ# #)
-- | Rounds towards zero.
--
foreign import prim "integer_cmm_quotIntegerzh" quotInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- | Rounds towards zero.
foreign import prim "integer_cmm_quotIntegerWordzh" quotIntegerWord#
:: Int# -> ByteArray# -> Word# -> MPZ#
-- | Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.
--
foreign import prim "integer_cmm_remIntegerzh" remInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- | Variant of 'remInteger#'
foreign import prim "integer_cmm_remIntegerWordzh" remIntegerWord#
:: Int# -> ByteArray# -> Word# -> MPZ#
-- | Compute div and mod simultaneously, where div rounds towards negative infinity
-- and\texttt{(q,r) = divModInteger\#(x,y)} implies \texttt{plusInteger\# (timesInteger\# q y) r = x}.
--
foreign import prim "integer_cmm_divModIntegerzh" divModInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> (# MPZ#, MPZ# #)
foreign import prim "integer_cmm_divModIntegerWordzh" divModIntegerWord#
:: Int# -> ByteArray# -> Word# -> (# MPZ#, MPZ# #)
foreign import prim "integer_cmm_divIntegerzh" divInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
foreign import prim "integer_cmm_divIntegerWordzh" divIntegerWord#
:: Int# -> ByteArray# -> Word# -> MPZ#
foreign import prim "integer_cmm_modIntegerzh" modInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
foreign import prim "integer_cmm_modIntegerWordzh" modIntegerWord#
:: Int# -> ByteArray# -> Word# -> MPZ#
-- | Divisor is guaranteed to be a factor of dividend.
--
foreign import prim "integer_cmm_divExactIntegerzh" divExactInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
foreign import prim "integer_cmm_divExactIntegerWordzh" divExactIntegerWord#
:: Int# -> ByteArray# -> Word# -> MPZ#
-- | Greatest common divisor.
--
foreign import prim "integer_cmm_gcdIntegerzh" gcdInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- | Extended greatest common divisor.
--
foreign import prim "integer_cmm_gcdExtIntegerzh" gcdExtInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> (# MPZ#, MPZ# #)
-- | Greatest common divisor, where second argument is an ordinary {\tt Int\#}.
--
foreign import prim "integer_cmm_gcdIntegerIntzh" gcdIntegerInt#
:: Int# -> ByteArray# -> Int# -> Int#
-- |
--
foreign import prim "integer_cmm_gcdIntzh" gcdInt#
:: Int# -> Int# -> Int#
-- | Convert to arbitrary-precision integer.
-- First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArray\#}
-- represent an {\tt Integer\#} holding the mantissa.
--
foreign import prim "integer_cmm_decodeDoublezh" decodeDouble#
:: Double# -> (# Int#, MPZ# #)
-- |
--
-- Note: This primitive doesn't use 'MPZ#' because its purpose is to instantiate a 'J#'-value.
foreign import prim "integer_cmm_int2Integerzh" int2Integer#
:: Int# -> (# Int#, ByteArray# #)
-- |
--
-- Note: This primitive doesn't use 'MPZ#' because its purpose is to instantiate a 'J#'-value.
foreign import prim "integer_cmm_word2Integerzh" word2Integer#
:: Word# -> (# Int#, ByteArray# #)
-- |
--
foreign import prim "integer_cmm_andIntegerzh" andInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_orIntegerzh" orInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_xorIntegerzh" xorInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_testBitIntegerzh" testBitInteger#
:: Int# -> ByteArray# -> Int# -> Int#
-- |
--
foreign import prim "integer_cmm_mul2ExpIntegerzh" mul2ExpInteger#
:: Int# -> ByteArray# -> Int# -> MPZ#
-- |
--
foreign import prim "integer_cmm_fdivQ2ExpIntegerzh" fdivQ2ExpInteger#
:: Int# -> ByteArray# -> Int# -> MPZ#
-- |
--
foreign import prim "integer_cmm_powIntegerzh" powInteger#
:: Int# -> ByteArray# -> Word# -> MPZ#
-- |
--
foreign import prim "integer_cmm_powModIntegerzh" powModInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_powModSecIntegerzh" powModSecInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_recipModIntegerzh" recipModInteger#
:: Int# -> ByteArray# -> Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_nextPrimeIntegerzh" nextPrimeInteger#
:: Int# -> ByteArray# -> MPZ#
-- |
--
foreign import prim "integer_cmm_testPrimeIntegerzh" testPrimeInteger#
:: Int# -> ByteArray# -> Int# -> Int#
-- |
--
foreign import prim "integer_cmm_sizeInBasezh" sizeInBaseInteger#
:: Int# -> ByteArray# -> Int# -> Word#
-- |
--
foreign import prim "integer_cmm_importIntegerFromByteArrayzh" importIntegerFromByteArray#
:: ByteArray# -> Word# -> Word# -> Int# -> MPZ#
-- |
--
foreign import prim "integer_cmm_importIntegerFromAddrzh" importIntegerFromAddr#
:: Addr# -> Word# -> Int# -> State# s -> (# State# s, MPZ# #)
-- |
--
foreign import prim "integer_cmm_exportIntegerToMutableByteArrayzh" exportIntegerToMutableByteArray#
:: Int# -> ByteArray# -> MutableByteArray# s -> Word# -> Int# -> State# s -> (# State# s, Word# #)
-- |
--
foreign import prim "integer_cmm_exportIntegerToAddrzh" exportIntegerToAddr#
:: Int# -> ByteArray# -> Addr# -> Int# -> State# s -> (# State# s, Word# #)
-- |
--
foreign import prim "integer_cmm_complementIntegerzh" complementInteger#
:: Int# -> ByteArray# -> MPZ#
#if WORD_SIZE_IN_BITS < 64
-- Note: This primitive doesn't use 'MPZ#' because its purpose is to instantiate a 'J#'-value.
foreign import prim "integer_cmm_int64ToIntegerzh" int64ToInteger#
:: Int64# -> (# Int#, ByteArray# #)
-- Note: This primitive doesn't use 'MPZ#' because its purpose is to instantiate a 'J#'-value.
foreign import prim "integer_cmm_word64ToIntegerzh" word64ToInteger#
:: Word64# -> (# Int#, ByteArray# #)
foreign import ccall unsafe "hs_integerToInt64"
integerToInt64# :: Int# -> ByteArray# -> Int64#
foreign import ccall unsafe "hs_integerToWord64"
integerToWord64# :: Int# -> ByteArray# -> Word64#
#endif
-- used to be primops:
integer2Int# :: Int# -> ByteArray# -> Int#
integer2Int# s d = if isTrue# (s ==# 0#)
then 0#
else let !v = indexIntArray# d 0# in
if isTrue# (s <# 0#)
then negateInt# v
else v
integer2Word# :: Int# -> ByteArray# -> Word#
integer2Word# s d = int2Word# (integer2Int# s d)
{-# LANGUAGE MagicHash, UnboxedTuples, NoImplicitPrelude #-}
module GHC.Integer.Logarithms
( integerLogBase#
, integerLog2#
, wordLog2#
) where
import GHC.Prim
import GHC.Integer
import qualified GHC.Integer.Logarithms.Internals as I
-- | Calculate the integer logarithm for an arbitrary base.
-- The base must be greater than 1, the second argument, the number
-- whose logarithm is sought, should be positive, otherwise the
-- result is meaningless.
--
-- > base ^ integerLogBase# base m <= m < base ^ (integerLogBase# base m + 1)
--
-- for @base > 1@ and @m > 0@.
integerLogBase# :: Integer -> Integer -> Int#
integerLogBase# b m = case step b of
(# _, e #) -> e
where
step pw =
if m `ltInteger` pw
then (# m, 0# #)
else case step (pw `timesInteger` pw) of
(# q, e #) ->
if q `ltInteger` pw
then (# q, 2# *# e #)
else (# q `quotInteger` pw, 2# *# e +# 1# #)
-- | Calculate the integer base 2 logarithm of an 'Integer'.
-- The calculation is more efficient than for the general case,
-- on platforms with 32- or 64-bit words much more efficient.
--
-- The argument must be strictly positive, that condition is /not/ checked.
integerLog2# :: Integer -> Int#
integerLog2# = I.integerLog2#
-- | This function calculates the integer base 2 logarithm of a 'Word#'.
wordLog2# :: Word# -> Int#
wordLog2# = I.wordLog2#
{-# LANGUAGE CPP, MagicHash, UnboxedTuples, NoImplicitPrelude #-}
{-# OPTIONS_HADDOCK hide #-}
#include "MachDeps.h"
-- Fast integer logarithms to base 2.
-- integerLog2# and wordLog2# are of general usefulness,
-- the others are only needed for a fast implementation of
-- fromRational.
-- Since they are needed in GHC.Float, we must expose this
-- module, but it should not show up in the docs.
module GHC.Integer.Logarithms.Internals
( integerLog2#
, integerLog2IsPowerOf2#
, wordLog2#
, roundingMode#
) where
import GHC.Prim
import GHC.Types (isTrue#)
import GHC.Integer.Type
-- When larger word sizes become common, add support for those,
-- it is not hard, just tedious.
#if (WORD_SIZE_IN_BITS != 32) && (WORD_SIZE_IN_BITS != 64)
-- Less than ideal implementations for strange word sizes
import GHC.Integer
default ()