-1796254192 `div` 357566600 == 5 ??
Dylan Thurston
dpt at lotus.bostoncoop.net
Fri Jun 28 15:54:50 EDT 2002
On Fri, Jun 28, 2002 at 10:24:13AM +0100, Malcolm Wallace wrote:
> Yes, -5`div`2 == -(5`div`2) == -2
> but (-5)`div`2 == -3
>
> Ghc 5.02.2 has the infix priority wrong, and interprets the former as the latter.
> But more bizarrely, ghc 5.02.2 gets this very wrong:
>
> Prelude> (-1796254192) `div` 357566600
> 5
Thanks for the clear summary.
I've investigated a little, and I think I've found the problem. Note
that 1796254192 and 357566600 are less than 2^31, so the division is
done with short integers; however, there sum is bigger than 2^31. Now
look at this code from PrelBase.hs:
> divInt#, modInt# :: Int# -> Int# -> Int#
> x# `divInt#` y#
> | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y#
> | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y#
> | otherwise = x# `quotInt#` y#
> x# `modInt#` y#
> | (x# ># 0#) && (y# <# 0#) ||
> (x# <# 0#) && (y# ># 0#) = if r# /=# 0# then r# +# y# else 0#
> | otherwise = r#
> where
> r# = x# `remInt#` y#
This was obviously written with no thought to possible overflow. This
code is from 5.02.2, but the same code seems to be in the CVS version
(in libraries/base/GHC/Base.lhs).
Assuming that quotInt# is correct, a version of divInt# which is
correct (I believe) is
> divInt# :: Int# -> Int# -> Int#
> x# `divInt#` y#
> | (x# ># 0#) && (y# <# 0#) = (x# -# 1#) `quotInt#` y# -# 1#
> | (x# <# 0#) && (y# ># 0#) = (x# +# 1#) `quotInt#` y# -# 1#
> | otherwise = x# `quotInt#` y#
By the way, a more efficient and transparent implementation of modInt#
is
> x# `modInt#` y# = if r# <# 0# then r# +# y# else r#
> where r# = x# `remInt#` y#
Best,
Dylan Thurston
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/glasgow-haskell-bugs/attachments/20020628/4f432432/attachment.bin
More information about the Glasgow-haskell-bugs
mailing list