全加算器を組合せて,ripple carry adder を作る.加算器とか懐しさ満点ですね.
これで,何桁の足し算にも対応できて,カンペキです!
;; 電子回路シミュレータに必要な関数定義を読み込み (add-load-path "/Users/ykiri/programming/SICP") (load "section3/simulator") ;;; 半加算器 (define (half-adder a b s c) (let ((d (make-wire)) (e (make-wire))) (or-gate a b d) (and-gate a b c) (inverter c e) (and-gate d e s) 'ok)) ;;; 全加算器 (define (full-adder a b c-in sum c-out) (let ((s (make-wire)) (c1 (make-wire)) (c2 (make-wire))) (half-adder b c-in s c1) (half-adder a s sum c2) (or-gate c1 c2 c-out) 'ok)) ;;; ripple carry adder (define (ripple-carry-adder A_k B_k S_k C) (if (null? A_k) 'ok ; リストの内容がなくなったとき終了 (let ((a-wire (car A_k)) (b-wire (car B_k)) (s-wire (car S_k)) (c-wire (make-wire))) (full-adder a-wire b-wire c-wire s-wire C) (ripple-carry-adder (cdr A_k) (cdr B_k) (cdr S_k) c-wire))))
今回は実は初めて gauche.test 使ってみた.
(use gauche.test) (test-start "for problem 3-30") (add-load-path "/Users/ykiri/programming/SICP") (load "section3/3-30.scm") (test-section "make-wires") ; inputs で指定した 2 進数の入力信号を作成 (define (make-wires . inputs) (map (lambda (value) (let ((wire (make-wire))) (set-signal! wire value) wire)) inputs)) ;;; まずは 11(2) + 01(2) = 100(2) のてすと (define A2 (make-wires 1 1)) (define B2 (make-wires 0 1)) (define S2 (make-wires 0 0)) (define carry (let ((c (make-wire))) (set-signal! c 0) c)) (test "length" 2 (lambda () (length A2))) (test "wire-value A1" 1 (lambda () (get-signal (car A2)))) (test "wire-value A2" 1 (lambda () (get-signal (cadr A2)))) (test "wire-value B1" 0 (lambda () (get-signal (car B2)))) (test "wire-value B2" 1 (lambda () (get-signal (cadr B2)))) (test "wire-value S1" 0 (lambda () (get-signal (car S2)))) (test "wire-value S2" 0 (lambda () (get-signal (cadr S2)))) (test-section "simulation 1") (define the-agenda (make-agenda)) (define inverter-delay 2) (define and-gate-delay 3) (define or-gate-delay 5) (ripple-carry-adder A2 B2 S2 carry) (propagate) (test "wire-value S2" 0 (lambda () (get-signal (cadr S2)))) (test "wire-value S1" 0 (lambda () (get-signal (car S2)))) (test "carry-value" 1 (lambda () (get-signal carry))) (current-time the-agenda) ;;; 次は 111(2) + 101(2) = 1100(2) のテスト (test-section "simulation 2") (define A3 (make-wires 1 1 1)) (define B3 (make-wires 1 0 1)) (define S3 (make-wires 0 0 0)) (define carry (let ((c (make-wire))) (set-signal! c 1) c)) (define the-agenda (make-agenda)) (ripple-carry-adder A3 B3 S3 carry) (propagate) (test "wire-value S3" 0 (lambda () (get-signal (caddr S3)))) (test "wire-value S2" 0 (lambda () (get-signal (cadr S3)))) (test "wire-value S1" 1 (lambda () (get-signal (car S3)))) (test "carry-value" 1 (lambda () (get-signal carry)))