莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          sicp 5.1節習題嘗試解答

          Posted on 2009-06-11 00:47 dennis 閱讀(1808) 評論(1)  編輯  收藏 所屬分類: my open-source 、計算機科學與基礎

          5.1 圖就不畫在機器上了,麻煩

          5.2 用寄存器語言描述5.1題中的階乘機器,加上了讀取和打印,這里的解答全部在實際的寄存機器中驗證過,但是仍然按照該節的表示法表示。

          (controller
            fac
          -loop
             (assign n (op read))
             (assign product (
          const 1))
             (assign counter (
          const 1))
            iter
          -loop
             (test (op 
          >) (reg counter) (reg n))
             (branch (label iter
          -done))
             (assign product (op 
          *) (reg product) (reg counter))
             (assign counter (op 
          +) (reg counter) (const 1))
             (
          goto (label iter-loop))
            iter
          -done
             (perform (op print) (reg product))
             (
          goto (label fac-loop)))
           
          5.3 牛頓法求平方根,將這個過程轉化為寄存器語言,第一個版本,假設good-enough?和improve都是基本過程,
          ;version1
          (controller
             sqrt
          -loop
              (test (op good
          -enough?) (reg guess))
              (branch (label sqrt
          -done))
              (assign guess (op improve) (reg guess))
              (
          goto (label good-enough))
             sqrt
          -done)

            第二個版本,展開good-enough?過程,
          ;version2
          (controller
             good
          -enough
              (assign t (op square) (reg guess))
              (assign t (op 
          -) (reg t) (reg x))
              (assign t (op abs) (reg t))
              (test (op 
          <) (reg t) (const 0.001))
              (branch (label sqrt
          -done))
              (assign guess (op improve) (reg guess))
              (
          goto (label good-enough))
             sqrt
          -done)
            最后,展開improve過程,
          ;version3
          (controller
            sqrt-init
             (assign guess (const 1.0))
             (assign x (op read))
            good
          -enough
              ;good
          -enough
             (assign t (op square) (reg guess))
             (assign t (op 
          -) (reg t) (reg x))
             (assign t (op abs) (reg t))
             (test (op 
          <) (reg t) (const 0.001))
             (branch (label sqrt
          -done))
              ;improve
             (assign t (op 
          /) (reg x) (reg guess))
             (assign t (op 
          +) (reg guess) (reg t))
             (assign guess (op 
          /) (reg t) (const 2.0))
             (
          goto (label good-enough))
            sqrt
          -done)
             在start之后,從寄存器guess中得到最后結果。

          5.4
          a)第一個是一個指數計算過程,用到了遞歸,因此需要引入continue寄存器來保存和恢復堆棧,實現與階乘相似,如下

          (controller
              (assign continue (label expt-done))
              expt
          -loop
                (test (op 
          =) (reg n) (const 0))
                (branch (label expt
          -base-case))
                ;;保存continue
                (save 
          continue)
                (assign n (op 
          -) (reg n) (const 1))
                (assign 
          continue (label after-expt))
                (
          goto (label expt-loop))
              after
          -expt
                ;;恢復continue
                (restore 
          continue)
                (assign val (op 
          *) (reg b) (reg val))
                (
          goto (reg continue))
              expt
          -base-case
                (assign val (
          const 1))
                (
          goto (reg continue))
              expt
          -done
                (perform (op display) (reg val)))

          b) 迭代型的遞歸計算過程,尾遞歸調用,因此不需要continue寄存器來保存和恢復堆棧,這道習題就是希望能分辨非尾遞歸和尾遞歸帶來的寄存機器語言的區別
          (controller
              (assign product (
          const 1))
              (assign n (op read))
              (assign b (op read))
              (assign counter (reg n))
             expt
          -iter-loop
               (test (op 
          =) (reg counter) (const 0))
               (branch (label expt
          -done))
               (assign counter (op 
          -) (reg counter) (const 1))
               (assign product (op 
          *) (reg b) (reg product))
               (
          goto (label expt-iter-loop))
             expt
          -done
                (perform (op display) (reg product)))

          5.5  手工模擬就算了,5.2節就可以機器模擬了

          5.6 是有一個多余的save和一個多余的restore操作,請看注釋:
          (
             (assign 
          continue (label fib-done))
            fib
          -loop
             (test (op 
          <) (reg n) (const 2))
             (branch (label immediate
          -answer))
             ;;compute fib(n
          -1)
             (save 
          continue)
             (assign 
          continue (label after-fib-1))
             (save n)
             (assign n (op 
          -) (reg n) (const 1))
             (
          goto (label fib-loop))
            after
          -fib-1 
             ;;compute fib(n
          -2)
             (restore n)
             ;這里多余,(restore 
          continue)
             (assign n (op 
          -) (reg n) (const 2))
             ;這里多余,(save 
          continue)
             (assign 
          continue (label after-fib-2))
             (save val) ;;save fib(n
          -1)
             (
          goto (label fib-loop))
            after
          -fib-2
             (assign n (reg val))
             (restore val)
             (restore 
          continue)
             (assign val (op 
          +) (reg val) (reg n))
             (
          goto (reg continue))
           immediate
          -answer
             (assign val (reg n))
             (
          goto (reg continue))
             
           fib
          -done)



            




          評論

          # re: sicp 5.1節習題嘗試解答  回復  更多評論   

          2009-06-11 09:55 by Arbow
          老莊又在苦練內功心法啦
          主站蜘蛛池模板: 陇川县| 遂宁市| 奈曼旗| 巴南区| 那曲县| 伊吾县| 玉溪市| 荥阳市| 呼和浩特市| 牡丹江市| 溆浦县| 台北县| 枝江市| 互助| 双城市| 获嘉县| 连江县| 深水埗区| 二连浩特市| 浦东新区| 塘沽区| 连州市| 漯河市| 张家口市| 龙江县| 芦山县| 无为县| 黄平县| 商水县| 沂水县| 赤峰市| 海盐县| 冕宁县| 吉安县| 普洱| 宁乡县| 峨边| 渝中区| 勃利县| 安乡县| 梓潼县|