diff options
author | Herbert Valerio Riedel <hvr@gnu.org> | 2014-02-02 12:18:20 +0100 |
---|---|---|
committer | Herbert Valerio Riedel <hvr@gnu.org> | 2014-02-02 12:49:58 +0100 |
commit | bcd38ea7f97cc3a3ed192bc0666c816c027bd9fc (patch) | |
tree | 521903b37368f4d7b1c58d4ed355eafd40f06dd6 /libraries/integer-gmp | |
parent | c7a050f1ca2df732f7310c1fa0b9c4963b89017e (diff) | |
download | haskell-bcd38ea7f97cc3a3ed192bc0666c816c027bd9fc.tar.gz |
Fix negation of `divMod`/`quotRem` results (fixes #8726)
High-level pseudo code of what the code was supposed to implement:
quotRem' :: Integer -> Integer -> (Integer,Integer)
quotRem' a b@(S# _)
| b < 0 = negFst . uncurry quotRem' . negSnd $ (a,b)
| otherwise = quotRemUI a (fromIntegral (abs b))
divMod' :: Integer -> Integer -> (Integer,Integer)
divMod' a b@(S# _)
| b < 0 = negSnd . uncurry divMod' . negBoth $ (a,b)
| otherwise = divModUI a (fromIntegral b)
negFst (q,r) = (-q,r)
negSnd (q,r) = ( q,-r)
negBoth (q,r) = (-q,-r)
-- quotRemUI and divModUI represent GMP's `mpz_{f,t}div_qr_ui()`
quotRemUI, divModUI :: Integer -> Word -> (Integer,Integer)
Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>
Diffstat (limited to 'libraries/integer-gmp')
-rw-r--r-- | libraries/integer-gmp/GHC/Integer/Type.lhs | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/libraries/integer-gmp/GHC/Integer/Type.lhs b/libraries/integer-gmp/GHC/Integer/Type.lhs index 8596562e49..3fb2ae67ec 100644 --- a/libraries/integer-gmp/GHC/Integer/Type.lhs +++ b/libraries/integer-gmp/GHC/Integer/Type.lhs @@ -296,9 +296,9 @@ quotRemInteger (S# i) (S# j) = case quotRemInt# i j of #if SIZEOF_HSWORD == SIZEOF_LONG quotRemInteger (J# s1 d1) (S# b) | isTrue# (b <# 0#) = case quotRemIntegerWord# s1 d1 (int2Word# (negateInt# b)) of - (# q, r #) -> let !q' = mpzToInteger(mpzNeg q) - !r' = mpzToInteger(mpzNeg r) - in (# q', r' #) + (# q, r #) -> let !q' = mpzToInteger (mpzNeg q) + !r' = mpzToInteger r + in (# q', r' #) -- see also Trac #8726 quotRemInteger (J# s1 d1) (S# b) = mpzToInteger2 (quotRemIntegerWord# s1 d1 (int2Word# b)) #else @@ -322,9 +322,9 @@ divModInteger (S# i) (S# j) = (# S# d, S# m #) #if SIZEOF_HSWORD == SIZEOF_LONG divModInteger (J# s1 d1) (S# b) | isTrue# (b <# 0#) = case divModIntegerWord# (negateInt# s1) d1 (int2Word# (negateInt# b)) of - (# q, r #) -> let !q' = mpzToInteger (mpzNeg q) - !r' = mpzToInteger r - in (# q', r' #) + (# q, r #) -> let !q' = mpzToInteger q + !r' = mpzToInteger (mpzNeg r) + in (# q', r' #) -- see also Trac #8726 divModInteger (J# s1 d1) (S# b) = mpzToInteger2(divModIntegerWord# s1 d1 (int2Word# b)) #else @@ -386,7 +386,7 @@ modInteger (S# a) (S# b) = S# (modInt# a b) modInteger ia@(S# _) ib@(J# _ _) = modInteger (toBig ia) ib #if SIZEOF_HSWORD == SIZEOF_LONG modInteger (J# sa a) (S# b) | isTrue# (b <# 0#) - = mpzToInteger (mpzNeg (remIntegerWord# (negateInt# sa) a (int2Word# (negateInt# b)))) + = mpzToInteger (mpzNeg (modIntegerWord# (negateInt# sa) a (int2Word# (negateInt# b)))) modInteger (J# sa a) (S# b) = mpzToInteger (modIntegerWord# sa a (int2Word# b)) #else |