Fix negation of `divMod`/`quotRem` results (fixes #8726)
authorHerbert Valerio Riedel <hvr@gnu.org>
Sun, 2 Feb 2014 11:18:20 +0000 (12:18 +0100)
committerHerbert Valerio Riedel <hvr@gnu.org>
Sun, 2 Feb 2014 11:49:58 +0000 (12:49 +0100)
commit2f841fdf5b33c4eb32cfc5d1b8207585f1880d9a
treeff65aca1a37a79351209884623eceafef68a38b8
parent753bb061971b06c2560a9f2a55a1fbed76efb7bc
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>
GHC/Integer/Type.lhs