Exercise 2.93: Modify the rational-arithmetic
package to use generic operations, but change make-rat so that it does
not attempt to reduce fractions to lowest terms. Test your system by calling
make-rational on two polynomials to produce a rational function:
(define p1 (make-polynomial 'x '((2 1) (0 1))))
(define p2 (make-polynomial 'x '((3 1) (0 1))))
(define rf (make-rational p2 p1))
Now add rf to itself, using add. You will observe that this
addition procedure does not reduce fractions to lowest terms.
We can reduce polynomial fractions to lowest terms using the same idea we used
with integers: modifying make-rat to divide both the numerator and the
denominator by their greatest common divisor. The notion of “greatest common
divisor” makes sense for polynomials. In fact, we can compute the
GCD of two polynomials using essentially the same Euclid’s Algorithm
that works for integers. The integer version is
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))
Using this, we could make the obvious modification to define a GCD
operation that works on term lists:
(define (gcd-terms a b)
(if (empty-termlist? b)
a
(gcd-terms b (remainder-terms a b))))
where remainder-terms picks out the remainder component of the list
returned by the term-list division operation div-terms that was
implemented in Exercise 2.91.
练习 2.93:修改有理算术包以使用通用操作,但修改 make-rat 使其不尝试将分数化为最简形式。通过对两个多项式调用 make-rational 来生成一个有理函数,以此测试你的系统:
(define p1 (make-polynomial 'x '((2 1) (0 1))))
(define p2 (make-polynomial 'x '((3 1) (0 1))))
(define rf (make-rational p2 p1))
现在用 add 将 rf 与自身相加。你会发现这个加法过程没有将分数化为最简形式。
我们可以用处理整数时相同的思路将多项式分数化为最简形式:修改 make-rat,在用给定的分子和分母构成有理数之前,将两者都除以它们的最大公因子。对多项式而言,"最大公因子"的概念是有意义的。事实上,我们可以用本质上与整数相同的欧几里得算法来计算两个多项式的最大公因子 (GCD)。整数版本为
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))
利用这一思路,可以对项表定义一个显而易见的 GCD 操作:
(define (gcd-terms a b)
(if (empty-termlist? b)
a
(gcd-terms b (remainder-terms a b))))
其中 remainder-terms 从练习 2.91 中实现的项表除法操作 div-terms 所返回的表中取出余式部分。
(define p1 (make-polynomial 'x '((2 1) (0 1))))
(define p2 (make-polynomial 'x '((3 1) (0 1))))
(define rf (make-rational p2 p1)) (define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b)))) (define (gcd-terms a b)
(if (empty-termlist? b)
a
(gcd-terms b (remainder-terms a b))))