Algorithms for functional programming: the blog

News and behind-the-scenes details on AFP: the book
Posts tagged as multiplicative inverse

Multiplicative-inverse bug in Ikarus Scheme

2011-08-22 by stone

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.