diff --git a/src/code/irrat.lisp b/src/code/irrat.lisp index 325e5bc6a629ad9095b4807c81928a167adf73f6..0804ef9ec89a03164005a313173fccf6b6707e04 100644 --- a/src/code/irrat.lisp +++ b/src/code/irrat.lisp @@ -653,10 +653,10 @@ ;; Number fits in a double, so it's easy (float (%log10 d) float-type)) (t - ;; Number doesn't fit in a double. Do it the hard way. - ;; This should be done more accurately. - (/ (log2 number float-type) - (log2 (float 10 float-type))))))) + ;; Number doesn't fit in a double. Do it the hard way using + ;; log2. This should be done more accurately. + (float (/ (log2 number) + (log2 10)) float-type))))) (defun log (number &optional (base nil base-p)) "Return the logarithm of NUMBER in the base BASE, which defaults to e." @@ -692,10 +692,14 @@ double-float) (log2 number 1d0)) #+double-double - (((foreach integer ratio single-float double-float) + (((foreach single-float double-float) double-double-float) (dd-%log2 (float number 1w0))) #+double-double + (((foreach integer ratio) + double-double-float) + (log2 number 1w0)) + #+double-double ((double-double-float (foreach integer ratio single-float double-float double-double-float)) (dd-%log2 number)))) @@ -722,7 +726,11 @@ double-float) (log10 number 1d0)) #+double-double - (((foreach integer ratio single-float double-float) + (((foreach integer ratio) + ext:double-double-float) + (log10 number 1w0)) + #+double-double + (((foreach single-float double-float) ext:double-double-float) (dd-%log10 (float number 1w0))) #+double-double diff --git a/tests/irrat.lisp b/tests/irrat.lisp index 95383940b296b247bb7d367a658241229c27f742..a6a405db8f6091cf275e3a2d6f4d234ab13be217 100644 --- a/tests/irrat.lisp +++ b/tests/irrat.lisp @@ -88,7 +88,12 @@ (let ((y (kernel::dd-%log2 (sqrt 0.5w0)))) (assert-true (<= (relerr y -1/2) (* 2.7 (scale-float 1d0 (- (float-digits 1w0))))) - y))) + y)) + (assert-true (typep (log (ash 1 3000) 2) 'single-float)) + (assert-true (typep (log (ash 1 3000) 2f0) 'single-float)) + (assert-true (typep (log (ash 1 3000) 2d0) 'double-float)) + (assert-true (typep (log (ash 1 3000) 2w0) 'ext:double-double-float))) + (define-test dd-log2.powers-of-2 (loop for k from -1074 below 1024 @@ -100,7 +105,11 @@ (define-test dd-log10.special-cases (let ((y (kernel::dd-%log10 (sqrt 10w0)))) (assert-true (<= (relerr y 1/2) - (* 0.25 (scale-float 1d0 (- (float-digits 1w0)))))))) + (* 0.25 (scale-float 1d0 (- (float-digits 1w0))))))) + (assert-true (typep (log (ash 1 3000) 10) 'single-float)) + (assert-true (typep (log (ash 1 3000) 10f0) 'single-float)) + (assert-true (typep (log (ash 1 3000) 10d0) 'double-float)) + (assert-true (typep (log (ash 1 3000) 10w0) 'ext:double-double-float))) (define-test dd-log10.powers-of-ten ;; It would be nice if dd-%log10 produce the exact result for powers