Multiplicative-inverse bug in Ikarus Scheme
In testing the examples from chapter 1 of AFP, I turned up a bug in
the Ikarus Scheme processor (version 0.0.3). One of my examples computes
the multiplicative inverse of -3/8, using the expression
(/ -3/8). The test code, then, was essentially
(= (/ -3/8) -8/3)
The test failed -- Ikarus Scheme returns #f as the value of
the equality test. I tried a few interactions to try to get some idea
of what was going on, but I found the results mystifying:
> (/ -3/8) 8/-3
This isn't exactly wrong, but the form of the number is not what I expecteed, since 8/-3 is not a valid R6RS literal. Ikarus Scheme accepts such literals as input, but appears to normalize them:
> 8/-3 -8/3
It looks like the one-argument / procedure is internally
generating a rational value with a negative denominator and not normalizing
the result:
> (rational? (/ -3/8)) #t > (numerator (/ -3/8)) 8 > (denominator (/ -3/8)) -3
Then the = predicate gets the wrong answer because it
somehow relies the precondition that denominators are positive. It's not
that the = predicate can't deal with signed values:
> (= -8/3 8/-3) #t > (= -8/-3 16/6) #t
Other procedures deal correctly with the negative-denominator rational:
> (< 8/-3 (/ -3/8)) #f > (> 8/-3 (/ -3/8)) #f > (<= 8/-3 (/ -3/8)) #t > (>= 8/-3 (/ -3/8)) #t > (- 8/-3 (/ -3/8)) 0
The two-argument form of the / procedure gives the correct
answer:
> (/ 1 -3/8) -8/3 > (= (/ -3/8) (/ 1 -3/8)) #f > (- (/ -3/8) (/ 1 -3/8)) 0
I looked over the list of bugs fixed in version 0.0.4 and didn't find this one, so I filed a bug report on the LaunchPad site for Ikarus Scheme.
Testing equality for exact rationals seems pretty straightforward -- you multiply the numerator of each one by the denominator of the other and determine whether the resulting integers are equal. But this should work even without the precondition that denominators be positive. I wonder what alternative approach the author of Ikarus Scheme used -- I must be missing something.