fast-digits 0.3.1.0 → 0.3.2.0
raw patch · 5 files changed
+33/−38 lines, 5 filesdep +ghc-bignumdep −integer-gmpdep ~QuickCheckdep ~basedep ~smallchecksetup-changedPVP ok
version bump matches the API change (PVP)
Dependencies added: ghc-bignum
Dependencies removed: integer-gmp
Dependency ranges changed: QuickCheck, base, smallcheck, tasty, tasty-bench, tasty-quickcheck, tasty-smallcheck
API changes (from Hackage documentation)
Files
- Setup.hs +0/−2
- changelog.md +4/−0
- fast-digits.cabal +15/−23
- src-internal/Data/FastDigits/Internal.hs +2/−1
- src/Data/FastDigits.hs +12/−12
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
changelog.md view
@@ -1,3 +1,7 @@+# 0.3.2.0++* Migrate from `integer-gmp` to `ghc-bignum`.+ # 0.3.1.0 * Performance improvement for decimal digits.
fast-digits.cabal view
@@ -1,5 +1,5 @@ name: fast-digits-version: 0.3.1.0+version: 0.3.2.0 license: GPL-3 license-file: LICENSE maintainer: andrew.lelechenko@gmail.com@@ -14,11 +14,11 @@ category: Data build-type: Simple cabal-version: 2.0-extra-source-files:+extra-doc-files: changelog.md README.md tested-with:- GHC ==7.10.3 GHC ==8.0.2 GHC ==8.2.2 GHC ==8.4.4 GHC ==8.6.5 GHC ==8.8.4 GHC ==8.10.4 GHC ==9.0.1+ GHC ==9.0.2 GHC ==9.2.8 GHC ==9.4.5 GHC ==9.6.2 source-repository head type: git@@ -29,12 +29,10 @@ Data.FastDigits hs-source-dirs: src default-language: Haskell2010- ghc-options: -Wall -O2 -fno-warn-deprecations- if impl(ghc >= 8.0)- ghc-options: -Wcompat+ ghc-options: -Wall -O2 -Wcompat build-depends:- base >=4.8 && <5,- integer-gmp >=1.0,+ base >=4.15 && <5,+ ghc-bignum <1.4, fast-digits-internal library fast-digits-internal@@ -42,9 +40,7 @@ Data.FastDigits.Internal hs-source-dirs: src-internal default-language: Haskell2010- ghc-options: -Wall -O2- if impl(ghc >= 8.0)- ghc-options: -Wcompat+ ghc-options: -Wall -O2 -Wcompat build-depends: base >=4.8 && <5 @@ -53,16 +49,14 @@ main-is: Tests.hs hs-source-dirs: tests default-language: Haskell2010- ghc-options: -Wall- if impl(ghc >= 8.0)- ghc-options: -Wcompat+ ghc-options: -Wall -Wcompat build-depends: base,- tasty,- tasty-quickcheck,- tasty-smallcheck,- QuickCheck,- smallcheck,+ tasty <1.5,+ tasty-quickcheck <0.11,+ tasty-smallcheck <0.9,+ QuickCheck <2.15,+ smallcheck <1.3, -- digits, fast-digits, fast-digits-internal@@ -72,11 +66,9 @@ main-is: Bench.hs hs-source-dirs: bench default-language: Haskell2010- ghc-options: -Wall -O2- if impl(ghc >= 8.0)- ghc-options: -Wcompat+ ghc-options: -Wall -O2 -Wcompat build-depends: base, -- digits, fast-digits,- tasty-bench >= 0.2.4+ tasty-bench >= 0.2.4 && <0.4
src-internal/Data/FastDigits/Internal.hs view
@@ -7,6 +7,7 @@ -} {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} @@ -32,7 +33,7 @@ where go pw = case timesWord2# pw pw of (# 0##, pw2 #)- -> let (# n, pw2n #) = go pw2 in+ -> let !(# n, pw2n #) = go pw2 in case timesWord2# pw pw2n of (# 0##, pw2n1 #) -> (#n `timesWord#` 2## `plusWord#` 1##, pw2n1 #) _ -> (# n `timesWord#` 2##, pw2n #)
src/Data/FastDigits.hs view
@@ -23,16 +23,16 @@ import Data.Bits (finiteBitSize) import GHC.Exts (Word#, Word(..), uncheckedShiftRL#, and#, timesWord2#, minusWord#, quotRemWord#, timesWord#, Int(..), iShiftRL#, isTrue#, word2Int#, (>#), (*#))-import GHC.Integer.GMP.Internals (GmpLimb#, BigNat, quotRemBigNatWord, isZeroBigNat, sizeofBigNat#) import Data.FastDigits.Internal (selectPower) import GHC.Natural (Natural(..))+import GHC.Num.BigNat (BigNat(..), bigNatIsZero, bigNatQuotRemWord#, bigNatSize#, BigNat#) -digitsNatural :: GmpLimb# -> BigNat -> [Word]+digitsNatural :: Word# -> BigNat# -> [Word] digitsNatural base = f where f n- | isZeroBigNat n = []- | otherwise = let !(# q, r #) = n `quotRemBigNatWord` base in+ | bigNatIsZero n = []+ | otherwise = let !(# q, r #) = n `bigNatQuotRemWord#` base in W# r : f q digitsWord :: Word# -> Word# -> [Word]@@ -91,12 +91,12 @@ -- | For a given base, power and precalculated base^power -- take an integer and return the list of its digits.-digitsNatural' :: Word# -> Word# -> Word# -> BigNat -> [Word]+digitsNatural' :: Word# -> Word# -> Word# -> BigNat# -> [Word] digitsNatural' base power poweredBase = f where- f :: BigNat -> [Word]- f n = let !(# q, r #) = n `quotRemBigNatWord` poweredBase in- if isZeroBigNat q+ f :: BigNat# -> [Word]+ f n = let !(# q, r #) = n `bigNatQuotRemWord#` poweredBase in+ if bigNatIsZero q then digitsWord base r else let !(# fr, lr #) = digitsWordL base power r in fr ++ replicate (I# (word2Int# lr)) 0 ++ f q@@ -111,16 +111,16 @@ -> Natural -> [Word] digitsUnsigned (W# base) (NatS# n) = digitsWord base n-digitsUnsigned (W# base) (NatJ# n)- | halfSize <- sizeofBigNat# n `iShiftRL#` 1#+digitsUnsigned (W# base) (NatJ# n@(BN# n#))+ | halfSize <- bigNatSize# n# `iShiftRL#` 1# , isTrue# (halfSize ># 128#) = let pow = I# (word2Int# power *# halfSize) in let (nHi, nLo) = NatJ# n `quotRem` (NatS# poweredBase ^ (I# halfSize)) in padUpTo pow (digitsUnsigned (W# base) nLo) ++ digitsUnsigned (W# base) nHi | otherwise = case power of- 1## -> digitsNatural base n- _ -> digitsNatural' base power poweredBase n+ 1## -> digitsNatural base n#+ _ -> digitsNatural' base power poweredBase n# where !(# power, poweredBase #) = selectPower base