[Haskell-cafe] quotRem and divMod
Shachaf Ben-Kiki
shachaf at gmail.com
Tue Jan 29 07:09:37 CET 2013
On Mon, Jan 28, 2013 at 4:27 PM, Artyom Kazak <artyom.kazak at gmail.com> wrote:
> Hi!
>
> I’ve always thought that `quotRem` is faster than `quot` + `rem`, since both
> `quot` and `rem` are just "wrappers" that compute both the quotient and the
> remainder and then just throw one out. However, today I looked into the
> implementation of `quotRem` for `Int32` and found out that it’s not true:
>
> quotRem x@(I32# x#) y@(I32# y#)
> | y == 0 = divZeroError
> | x == minBound && y == (-1) = overflowError
> | otherwise = (I32# (narrow32Int# (x# `quotInt#`
> y#)),
> I32# (narrow32Int# (x# `remInt#`
> y#)))
>
> Why? The `DIV` instruction computes both, doesn’t it? And yet it’s being
> performed twice here. Couldn’t one of the experts clarify this bit?
>
That code is from base 4.5. Here's base 4.6:
quotRem x@(I32# x#) y@(I32# y#)
| y == 0 = divZeroError
-- Note [Order of tests]
| y == (-1) && x == minBound = (overflowError, 0)
| otherwise = case x# `quotRemInt#` y# of
(# q, r #) ->
(I32# (narrow32Int# q),
I32# (narrow32Int# r))
So it looks like it was improved in GHC 7.6. In particular, by this
commit: http://www.haskell.org/pipermail/cvs-libraries/2012-February/014880.html
Shachaf
More information about the Haskell-Cafe
mailing list