X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fnumbers.lisp;h=a62eb9d107232809fbf40290b6f3c240415735ef;hb=4f2091cda26c2f3004a31704910344bce3288eea;hp=34ad585768b18edd4d9e60e711cbc120626a87d6;hpb=b0fab8a8c774f4e2921877c408ecca0b39d38676;p=sbcl.git diff --git a/src/code/numbers.lisp b/src/code/numbers.lisp index 34ad585..a62eb9d 100644 --- a/src/code/numbers.lisp +++ b/src/code/numbers.lisp @@ -578,7 +578,7 @@ (numerator divisor)))) (values q (- number (* q divisor))))) ((fixnum bignum) - (values 0 number)) + (bignum-truncate (make-small-bignum number) divisor)) ((ratio (or float rational)) (let ((q (truncate (numerator number) (* (denominator number) divisor)))) @@ -1336,3 +1336,30 @@ (def minusp "Is this real number strictly negative?") (def oddp "Is this integer odd?") (def evenp "Is this integer even?")) + +;;;; modular functions +#. +(collect ((forms)) + (flet ((definition (name lambda-list width pattern) + ;; We rely on (SUBTYPEP `(UNSIGNED-BYTE ,WIDTH) + ;; 'BIGNUM-ELEMENT-TYPE) + `(defun ,name ,lambda-list + (flet ((prepare-argument (x) + (declare (integer x)) + (etypecase x + ((unsigned-byte ,width) x) + (bignum-element-type (logand x ,pattern)) + (fixnum (logand x ,pattern)) + (bignum (logand (%bignum-ref x 0) ,pattern))))) + (,name ,@(loop for arg in lambda-list + collect `(prepare-argument ,arg))))))) + (loop for infos being each hash-value of sb!c::*modular-funs* + ;; FIXME: We need to process only "toplevel" functions + unless (eq infos :good) + do (loop for info in infos + for name = (sb!c::modular-fun-info-name info) + and width = (sb!c::modular-fun-info-width info) + and lambda-list = (sb!c::modular-fun-info-lambda-list info) + for pattern = (1- (ash 1 width)) + do (forms (definition name lambda-list width pattern))))) + `(progn ,@(forms)))