DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> AJAX入門 >> AJAX詳解 >> sicp習題試解 (1.7)
sicp習題試解 (1.7)
編輯:AJAX詳解     
; ======================================================================
;
;          Structure and Interpretation of Computer Programs
;                  (trial answer to excercises)
;
;                  計算機程序的構造和解釋(習題試解)
;
;                                             created: code17 02/24/05
;                                             modifIEd:
; (保持內容完整不變前提下,可以任意轉載)
; ======================================================================

;; SICP No.1.7
;; 本期第一部分為理解題,第二部分為編程

;; 理解部分:關於誤差
;; 函數"good-enough?"在參數值較大和較小時均會產生誤差問題
;; (1) 正常的計算都會產生誤差,比如1/3是無限循環小數,有無數個有效位(從
;;     左端的一個不為0的數字起至右端最後一位不為0的數字止),而在計算機中
;;     或任何其他形式的機械計算中,分配給每個數字的存儲空間都是有限位的。
;;     因此捨入誤差在所難免。但在一般的普通計算中,因為計算機已經提供了
;;     相當多的存儲位,右端較低位次上需要捨入的量級往往非常小,大部分情
;;     況下對計算結果沒什麼影響。
;; (2) 但當運算結果很大時,小數點左邊位數很多,所進行捨入和非捨入的分界
;;     位置就可能很高,因此誤差就會很大。設想一個最簡單的模型,一共有10
;;     個有效位(小數點和其他控制位另算),那麼1.234567890123捨入為
;;     1.234567890,捨入誤差為0.000000000123;而同樣有效位的1234567890123
;;     則捨入為1234567890000,捨入誤差為123,也就是說所有的1234567890xxx
;;     在計算存儲以後只能獲得同樣的結果。因此在good-enough?的定義中,當參
;;     數很大時,自動的捨入誤差已經相當大,絕對誤差很大的數也可能被捨入為
;;     同樣的數值,從而導致判斷為good-enough,
;;     > (* 123456789.1 123456789.1)
;;     15241578774881878.0
;;     ;; 實際值15241578774881878.81,捨入誤差0.81,所以
;;     > (good-enough? 123456789.1 15241578774881878)
;;     #t
;;     ;; 而根據表達式(square guess)和x的實際差是0.81>>>0.001
;; (3) 當參數很小時,同樣會發生捨入誤差。但正如我們所說的低位的捨入誤差
;;     絕對值很小。問題在於,在一個固定的絕對誤差標准(比如這裡的<0.001)
;;     下,如果參數本身的量級足夠小,那麼這個絕對誤差標准所允許的誤差相
;;     對於參數本身的相對誤差可能是驚人的。比如
;;     > (good-enough? 0.00001 0.0000000001)
;;     #t
;;     ;; 准確值0.00001 * 0.00001 = 0.0000000001
;;     > (good-enough? 0.0001 0.0000000001)
;;     #t
;;     ;; 比准確值大了10倍的0.0001,一樣可以通過測試。因為
;;     ;; 0.0001 * 0.0001 -0.0000000001 同樣小於0.0001
;;     和上一種情況不同,這裡的判斷是嚴格符合我們的程序邏輯的,而不是
;;     自動的捨入造成的問題(這裡的有效位是1位),但這樣的結果是沒有意義的。
;;     而問題在於在這個問題中,無論我們規定多小的誤差標准,總存在足夠小的
;;     參數使得這種絕對誤差標准沒有意義。
;; 由此可見,首先,在考慮誤差相關的計算時,應該盡量避免過大的操作數,在
;; 原始的good-enough?定義中,比較(square guess) 和 x 不如比較guess和
;; (/ x guess),這兩種方法有著類似的含義,但後者的運算數的量級遠小於前者。
;; 其次使用絕對誤差在很多情況下是有問題的,而使用相對誤差控制顯然可以
;; 解決(3)中的問題,在某些情況下也可以降低運算數的量級從而改善(2)。


;; 程序部分:
(define (average x y)
  (/ (+ x y)
     2))
(define (improve guess x)
    (average guess
             (/ x guess)))
(define (good-enough? oldguess guess)
  (< (abs (/ (- guess oldguess)
             guess))
     0.001))
(define (sqrt-iter oldguess guess x)
  (if (good-enough? oldguess guess)
      guess
      (sqrt-iter guess
                 (improve guess x)
                 x)))
(define (sqrt x)
  (sqrt-iter 0.1 1.0 x))

;; Test-it
;; > (sqrt 2)
;; 1.4142135623746899
;; > (sqrt 9)
;; 3.000000001396984
;; >
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved