+75
−9
Loading
Take the rule of float precision contagion (CLHS 12.1.4.4) to also
mean that the result should be as accurate as the most accurate
argument. Effectively, all args are coerced to the highest precision
first before computing expt.
There's a simple test program to check that every case is covered with
the expected precision. (I think).
(defun test-expt ()
(dolist (base '(2 2f0 2d0 2w0) t)
(dolist (power '(1/2 .5f0 .5d0 .5w0))
(flet ((test-it (b p a eps expected)
(let* ((res (expt b p))
(absdiff (abs (- res a))))
(unless
(or (typep (realpart res) (type-of expected))
(<= absdiff (* 10 eps)))
(format t "FAILED: ~A^~A = ~A (~A)~%" b p res a)))))
;; Compute base^power.
(let* ((expected-type
(let ((prod (* base power)))
(if (rationalp prod)
1f0
prod)))
(eps (etypecase expected-type
((or rational single-float)
single-float-epsilon)
(double-float
double-float-epsilon)
(double-double-float
1w-31)))
(answer (sqrt (float base expected-type))))
(test-it base power answer eps expected-type)
(test-it base (complex power) answer eps expected-type)
(test-it (complex base) power answer eps expected-type)
(test-it (complex base) (complex power) eps answer expected-type))))))