minBound `rem` (-1) fails
I would expect both of the following operations to return 0, on the grounds that anything rem/mod -1 is zero:
Prelude> (minBound :: Int) `rem` (-1)
*** Exception: arithmetic overflow
Prelude> (minBound :: Int) `mod` (-1)
*** Exception: arithmetic overflow
In GHC 6.8.2, the instances of Integral for the various integer types explicitly check for this case and throw the error:
rem x@(I32# x#) y@(I32# y#)
| y == 0 = divZeroError
| x == minBound && y == (-1) = overflowError
| otherwise = I32# (x# `remInt32#` y#)
The current behaviour makes some sense in that rem/mod's behaviours are defined in terms of quot/div which can't give a sensible output for these input values -- but I can't really see anything wrong with changing the second guard there to return 0
.
(I ran into this while implementing constant expression folding in a compiler for the occam programming language; the occam compiler test suite explicitly checks that minBound
rem (-1) == 0
.)
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries/base |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |