SICP 読み (60) 2.5.1 汎用算術演算

問題 2.78 を元に 2.79 と 2.80 を。基本的には easy だと思っているんですがどうなるか。

問題 2.79

試験ドリブンという事で試験から検討を。
基本的には equ? が true のケースと false のケースが確認できれば良いはずなので scheme-number だとこうなるか。

   ("equ? test"
    (let ((t1 (make-scheme-number 6))
	  (t2 (make-scheme-number 6))
	  (t3 (make-scheme-number 7)))
      (assert-true (equ? t1 t2))
      (assert-false (equ? t1 t3))
      )
    )

以下を追加。最初、トップレベルで equ? を define してなくてびっくり。

(define (equ? x y) (apply-generic 'equ? x y))

(define (install-scheme-number-package)
  (put 'add '(scheme-number scheme-number) +)
  (put 'sub '(scheme-number scheme-number) -)
  (put 'mul '(scheme-number scheme-number) *)
  (put 'div '(scheme-number scheme-number) /)
  (put 'make 'scheme-number
       (lambda (x) x))
  (put 'equ? '(scheme-number scheme-number) =)
  'done)

試験パス。数値演算なので = で良いはず。

次は有理数パケジの試験を以下に。

   ("equ? test"
    (let ((t1 (make-rational 1 5))
	  (t2 (make-rational 2 10))
	  (t3 (make-rational 2 5)))
      (assert-true (equ? t1 t2))
      (assert-false (equ? t1 t3))
      )
    )

ええと。実装はどうすりゃいいのかな??
rational パケジに以下を追加。

 (define (equ-rat? x y)
   (and (= (numer x) (numer y))
	(= (denom x) (denom y))))

 (put 'equ? '(rational rational) equ-rat?)

試験はパス。最後が一番ハードル高そげ。試験なんですが、どうすれば良いのか。今までの経験から以下のケースは equ? な判断が微妙。

(assert-true (equ? (make-complex-from-real-imag (sqrt 3) 1)
		   (make-complex-from-mag-ang 2 (/ pi 6))))

もう少し見てみます。

gosh> (make-complex-from-real-imag (sqrt 3) 1)
(complex rectangular 1.7320508075688772 . 1)
gosh> (make-complex-from-mag-ang 2 (/ pi 6))
(complex polar 2 . 0.5235987755982988)
gosh> (magnitude (make-complex-from-real-imag (sqrt 3) 1))
2.0
gosh> (angle (make-complex-from-real-imag (sqrt 3) 1))
0.5235987755982989
gosh> (/ pi 6)
0.5235987755982988
gosh> (real-part (make-complex-from-mag-ang 2 (/ pi 6)))
1.7320508075688774
gosh> (sqrt 3)
1.7320508075688772
gosh> (imag-part (make-complex-from-mag-ang 2 (/ pi 6)))
0.9999999999999999
gosh>

rectangular と polar の比較だったら error というのが一番 easy な解なんですが、そんなコトは認められないんだろうなぁ。(困

ちょっと頭をヒヤさせて下さひ。