diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2020-07-28 11:30:44 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-07-29 15:09:02 -0400 |
commit | 96c31ea1f0303ebabc59edccff2e88444fe02722 (patch) | |
tree | b3da29f2cfdd29b1f1e479be215e6478cedb3e82 | |
parent | e3db4b4c5b7f5d2a62ebd88e174fca07d04c4e18 (diff) | |
download | haskell-96c31ea1f0303ebabc59edccff2e88444fe02722.tar.gz |
Fix bug in Natural multiplication (fix #18509)
A bug was lingering in Natural multiplication (inverting two limbs)
despite QuickCheck tests used during the development leading to wrong
results (independently of the selected backend).
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/BigNat.hs | 4 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/Natural.hs | 4 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/WordArray.hs | 10 | ||||
-rw-r--r-- | testsuite/tests/numeric/should_run/T18509.hs | 6 | ||||
-rw-r--r-- | testsuite/tests/numeric/should_run/T18509.stdout | 2 | ||||
-rw-r--r-- | testsuite/tests/numeric/should_run/all.T | 1 |
6 files changed, 19 insertions, 8 deletions
diff --git a/libraries/ghc-bignum/src/GHC/Num/BigNat.hs b/libraries/ghc-bignum/src/GHC/Num/BigNat.hs index 20a227f099..4aeedafc9d 100644 --- a/libraries/ghc-bignum/src/GHC/Num/BigNat.hs +++ b/libraries/ghc-bignum/src/GHC/Num/BigNat.hs @@ -228,8 +228,8 @@ bigNatToWordList bn = go (bigNatSize# bn) -- | Convert two Word# (most-significant first) into a BigNat bigNatFromWord2# :: Word# -> Word# -> BigNat# bigNatFromWord2# 0## 0## = bigNatZero# (# #) -bigNatFromWord2# 0## n = bigNatFromWord# n -bigNatFromWord2# w1 w2 = wordArrayFromWord2# w1 w2 +bigNatFromWord2# 0## l = bigNatFromWord# l +bigNatFromWord2# h l = wordArrayFromWord2# h l -- | Convert a BigNat into a Word# bigNatToWord# :: BigNat# -> Word# diff --git a/libraries/ghc-bignum/src/GHC/Num/Natural.hs b/libraries/ghc-bignum/src/GHC/Num/Natural.hs index ac35b65522..62e9f33e1c 100644 --- a/libraries/ghc-bignum/src/GHC/Num/Natural.hs +++ b/libraries/ghc-bignum/src/GHC/Num/Natural.hs @@ -86,8 +86,8 @@ naturalFromWord# x = NS x -- | Convert two Word# (most-significant first) into a Natural naturalFromWord2# :: Word# -> Word# -> Natural naturalFromWord2# 0## 0## = naturalZero -naturalFromWord2# 0## n = NS n -naturalFromWord2# w1 w2 = NB (bigNatFromWord2# w2 w1) +naturalFromWord2# 0## l = NS l +naturalFromWord2# h l = NB (bigNatFromWord2# h l) -- | Create a Natural from a Word naturalFromWord :: Word -> Natural diff --git a/libraries/ghc-bignum/src/GHC/Num/WordArray.hs b/libraries/ghc-bignum/src/GHC/Num/WordArray.hs index 78c450b55e..9b98f74293 100644 --- a/libraries/ghc-bignum/src/GHC/Num/WordArray.hs +++ b/libraries/ghc-bignum/src/GHC/Num/WordArray.hs @@ -121,12 +121,14 @@ withNewWordArrayTrimedMaybe# sz act = case runRW# io of (# _, a #) -> a -- | Create a WordArray# from two Word# -- --- `byteArrayFromWord2# msw lsw = lsw:msw` +-- `wordArrayFromWord2# h l +-- where h is the most significant word +-- l is the least significant word wordArrayFromWord2# :: Word# -> Word# -> WordArray# -wordArrayFromWord2# msw lsw = +wordArrayFromWord2# h l = withNewWordArray# 2# \mwa s -> - case mwaWrite# mwa 0# lsw s of - s -> mwaWrite# mwa 1# msw s + case mwaWrite# mwa 0# l s of + s -> mwaWrite# mwa 1# h s -- | Create a WordArray# from one Word# wordArrayFromWord# :: Word# -> WordArray# diff --git a/testsuite/tests/numeric/should_run/T18509.hs b/testsuite/tests/numeric/should_run/T18509.hs new file mode 100644 index 0000000000..fe4df42b14 --- /dev/null +++ b/testsuite/tests/numeric/should_run/T18509.hs @@ -0,0 +1,6 @@ +import Numeric.Natural + +main :: IO () +main = do + print $ (0xFFFFFFFF0 * 0xFFFFFFFF0 :: Natural) + print $ (2 :: Natural) ^ (190 :: Int) diff --git a/testsuite/tests/numeric/should_run/T18509.stdout b/testsuite/tests/numeric/should_run/T18509.stdout new file mode 100644 index 0000000000..4f0e5fd092 --- /dev/null +++ b/testsuite/tests/numeric/should_run/T18509.stdout @@ -0,0 +1,2 @@ +4722366480670621958400 +1569275433846670190958947355801916604025588861116008628224 diff --git a/testsuite/tests/numeric/should_run/all.T b/testsuite/tests/numeric/should_run/all.T index faa4d7c992..f8d6ea3d4d 100644 --- a/testsuite/tests/numeric/should_run/all.T +++ b/testsuite/tests/numeric/should_run/all.T @@ -71,3 +71,4 @@ test('T497', normal, compile_and_run, ['-O']) test('T17303', normal, compile_and_run, ['']) test('T18359', normal, compile_and_run, ['']) test('T18499', normal, compile_and_run, ['']) +test('T18509', normal, compile_and_run, ['']) |