Skip to content

Commit

Permalink
math: add ceiling-log
Browse files Browse the repository at this point in the history
  • Loading branch information
yitzchak committed Jul 26, 2024
1 parent 369f2f7 commit 99e3cb5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
62 changes: 62 additions & 0 deletions code/math/log.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
(in-package #:quaviver.math)

(declaim (ftype (function ((integer 2 36) unsigned-byte) (unsigned-byte 22))
ceiling-log
count-digits)
(inline ceiling-log
count-digits))

(defvar *ceiling-log-table*
(compute-ceiling-log +min-base+ +max-base+
(quaviver:arithmetic-size #+quaviver/long-float
'long-float
#-quaviver/long-float
'double-float)))

(defun ceiling-log (base value)
(declare (optimize speed))
(cond ((eql base 2)
(integer-length value))
((= (logcount base) 1)
(values (ceiling (integer-length value)
(1- (integer-length base)))))
(t
(let* ((value-length (integer-length value))
(lower (ceiling-log-expt base 2 (1- value-length)))
(upper (ceiling-log-expt base 2 value-length)))
(if (or (= lower upper)
(< value
(let ((table (svref *ceiling-log-table* (- base +min-base+))))
(if (< lower (length table))
(svref table lower)
(cl:expt base lower)))))
lower
upper)))))

(define-compiler-macro ceiling-log (&whole whole base value)
(cond ((not (constantp base))
whole)
((eql base 2)
`(integer-length ,value))
((= (logcount base) 1)
`(values (ceiling (integer-length ,value)
,(1- (integer-length base)))))
(t
`(let* ((value ,value)
(value-length (integer-length value))
(lower (ceiling-log-expt ,base 2 (1- value-length)))
(upper (ceiling-log-expt ,base 2 value-length)))
(declare (optimize speed))
(if (or (= lower upper)
(< value
(let ((table ,(svref *ceiling-log-table* (- base +min-base+))))
(if (< lower (length table))
(svref table lower)
(cl:expt ,base lower)))))
lower
upper)))))

(defun count-digits (base value)
(declare (optimize speed))
(max (ceiling-log base value)
1))
10 changes: 10 additions & 0 deletions code/math/utility.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,13 @@
do (setf (getf tables arithmetic-size)
(max (getf tables arithmetic-size 0)
bound))))

(defun compute-ceiling-log (min-base max-base width)
(make-array (- max-base min-base -1)
:initial-contents
(loop for base from min-base upto max-base
for max-power = (floor (log (ash 1 (1- width)) base))
collect (make-array (1+ max-power)
:initial-contents
(loop for power from 0 upto max-power
collect (cl:expt base power))))))
4 changes: 3 additions & 1 deletion code/packages.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@
#:floor-multiply/64-128q128
#:floor-multiply/evenp/64-128q128
#:floor-log-expt
#:ceiling-log-expt))
#:ceiling-log-expt
#:ceiling-log
#:count-digits))

#+sbcl
(pushnew :quaviver.math/smallnum *features*)
Expand Down
1 change: 1 addition & 0 deletions quaviver.asd
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
:serial t
:components ((:file "log-expt")
(:file "utility")
(:file "log")
(:file "implementation")
(:file "expt")
(:file "round-to-odd")))
Expand Down

0 comments on commit 99e3cb5

Please sign in to comment.