Has anyone else worked on exercise 13.3(b) in "ANSI Common Lisp"? I approached it by declaring all the variables in Figure 9.2 as long-floats:
; Use declarations in math utilities:
(defun sq (x)
(declare (long-float x))
(* x x))
(defun mag (x y z)
(declare (long-float x y z))
(sqrt (+ (sq x) (sq y) (sq z))))
(defun unit-vector (x y z)
(declare (long-float x y z))
(let ((d (mag x y z)))
(declare (long-float d))
(values (/ x d) (/ y d) (/ z d))))
(defstruct (point (:conc-name nil))
x y z)
(defun distance (p1 p2)
(mag (- (x p1) (x p2))
(- (y p1) (y p2))
(- (z p1) (z p2))))
(defun minroot (a b c)
(declare (long-float a b c))
(if (zerop a)
(/ (- c) b)
(let ((disc (- (sq b) (* 4 a c))))
(declare (long-float disc))
(unless (minusp disc)
(let ((discrt (sqrt disc)))
(declare (long-float discrt))
(min (/ (+ (- b) discrt) (* 2 a))
(/ (- (- b) discrt) (* 2 a))))))))
However, the running time slowed down as a result of this change, rather than sped up.Note that I used long-floats, rather than double-floats, because, when I used double-floats, the output was slightly different (only off by 1 on some values) than the original version in which variables were undeclared. However, the output was slightly different with long-floats, too, so I guess that didn't help.
Anyway, should declaring these variables make the program faster, or am I doing the problem incorrectly? And why is the output slightly different if I'm using the largest size floating-points? Below is the diff:
diff "spheres.pgm copy" spheres.pgm
125c125
61
179c179
61
6837,6838c6837,6838
42
> 118
6866,6867c6866,6867
118
> 42
7028c7028
23
7076c7076
23
7138c7138
113
7166c7166
113
7226c7226
117
7278c7278
117
7416,7417c7416,7417
84
> 53
7434c7434
86
7470c7470
86
7487,7488c7487,7488
53
> 84
7531c7531
18
7539c7539
19
7565c7565
19
7573c7573
18
7831c7831
116
7873c7873
116
7937c7937
18
7967c7967
18
8006c8006
108
8008c8008
127
8018c8018
23
8086c8086
23
8096c8096
127
8098c8098
108
8152c8152
163
8707c8707
111
8797c8797
111