[commit: packages/integer-gmp] master: Fix negation of `divMod`/`quotRem` results (fixes #8726) (2f841fd)

git at git.haskell.org git at git.haskell.org
Sun Feb 2 13:18:00 UTC 2014


Repository : ssh://git@git.haskell.org/integer-gmp

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/2f841fdf5b33c4eb32cfc5d1b8207585f1880d9a/integer-gmp

>---------------------------------------------------------------

commit 2f841fdf5b33c4eb32cfc5d1b8207585f1880d9a
Author: Herbert Valerio Riedel <hvr at gnu.org>
Date:   Sun Feb 2 12:18:20 2014 +0100

    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 at gnu.org>


>---------------------------------------------------------------

2f841fdf5b33c4eb32cfc5d1b8207585f1880d9a
 GHC/Integer/Type.lhs |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/GHC/Integer/Type.lhs b/GHC/Integer/Type.lhs
index 8596562..3fb2ae6 100644
--- a/GHC/Integer/Type.lhs
+++ b/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



More information about the ghc-commits mailing list