Skip to content
Snippets Groups Projects
Commit 55d04a31 authored by Raymond Toy's avatar Raymond Toy
Browse files

Fix up a few more issues with log.

 * src/code/irrat.lisp:
   * In log10, return the correct type for the result.  Previously, we
     would return a double even if a single were desired.
   * Fix up a few more cases where we failed to handle log of a huge
     rational correctly for log base 2 and base 10.
 * tests/irrat.lisp:
   * Add some tests to check that log returns the correct type of
     number for the log base 2 and 10 of very large rationals.
parent 37d383ae
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment