Exercise 1.7. The good-enough? test used in computing square roots
will not be very effective for finding the square roots of very small
numbers. Also, in real computers, arithmetic operations are almost
always performed with limited precision. This makes our test
inadequate for very large numbers. Explain these statements, with
examples showing how the test fails for small and large numbers. An
alternative strategy for implementing good-enough? is to watch how
guess changes from one iteration to the next and to stop when the
change is a very small fraction of the guess. Design a square-root
procedure that uses this kind of end test. Does this work better for
small and large numbers?
문제 원문입니다.
아주 작은 숫자의 경우에는 책에 주어진 good-enough?로 제곱근을 찾는 것이 별로 효과적이지 않다.
=> 이부분은 황천의달님이나 Jin님 말씀처럼 너무 작은 숫자의 경우에는 제곱의 차이가 비교값 보다 작기 때문으로 보입니다.
그리고 아주 큰 숫자의 경우는 부동 소수점의 유효숫자와 관련하여 정확한 값을 내지 못하는 경우를 찾으면 될 것 같습니다.
테스트 해본 바로 scheme의 부동소숫점 표기는 IEEE 754 standard의 Double precision을 따르는 것으
로 보이는데 이 때문에 무한정 큰 숫자를 표시할 수는 없습니다.
부동소숫점 표기와 관련된 내용은 아래 두 링크를 참고..
http://en.wikipedia.org/wiki/Double_precision
http://www.winapi.co.kr/clec/cpp2/18-1-4.htm
첫번째 링크에서 보면 double precision으로 표기할 수 있는 가장 큰 숫자는 1.7976931348623157 x
10^308이 됩니다.
계산을 쉽게 하기 위해서 x^n을 구해주는 함수를 정의했습니다.
(define (pow x y)
(define (pow-iter p y)
(if (= y 0 ) p (pow-iter (* p x) (- y 1))))
(pow-iter 1 y))
이 함수로 Max 값을 구하고 여기에 특정값을 더하거나 곱해 보았습니다.
> (+ 0.1 (* 1.7976931348623157 (pow 10 308)))
1.7976931348623157e+308
> (+ 1 (* 1.7976931348623157 (pow 10 308)))
1.7976931348623157e+308
> (+ 10 (* 1.7976931348623157 (pow 10 308)))
1.7976931348623157e+308
> (* 0.1 (* 1.7976931348623157 (pow 10 308)))
1.7976931348623158e+307
> (* 1 (* 1.7976931348623157 (pow 10 308)))
1.7976931348623157e+308
> (* 1.0 (* 1.7976931348623157 (pow 10 308)))
1.7976931348623157e+308
> (* 1.1 (* 1.7976931348623157 (pow 10 308)))
+inf.0
> (* 2 (* 1.7976931348623157 (pow 10 308)))
+inf.0
> (* 10 (* 1.7976931348623157 (pow 10 308)))
+inf.0
덧셈의 경우는 무슨 이유인지 모르겠지만 계속 같은 값이 나오고, 곱셈의 경우는 조금만(1 이상) 배가 되도 inf가 되버립니
다. 만약 근사값이나 근사값의 제곱이 +inf.0이 되버리면 good-enough?에서 정상적으로 비교가 이루어지지 않을 것 같
습니다. (무한대 - 어떤 수 = 무한대 라서 그럴 것 같은..)
double max 값을 sqrt 함수 안에 넣어봤는데 tail recursion이라 stack fault는 안나는데 계속 무
한 루프를 도는 것 같네요.