X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcode%2Fbignum.lisp;h=03f23377ab672d40899065e3c00ab4d75fc8a280;hb=62c09fabe8aa8f1bd75bf4db4c20e195a1b6bc1d;hp=cf70586301619c9861adafa8ff315ad80bf5509c;hpb=93ba859423ec6e035a7b22a76a2ac70038691d65;p=sbcl.git diff --git a/src/code/bignum.lisp b/src/code/bignum.lisp index cf70586..03f2337 100644 --- a/src/code/bignum.lisp +++ b/src/code/bignum.lisp @@ -22,7 +22,7 @@ ;;; bignum-logical-and bignum-logical-ior bignum-logical-xor ;;; bignum-logical-not bignum-load-byte bignum-deposit-byte ;;; bignum-truncate bignum-plus-p bignum-compare make-small-bignum -;;; bignum-logcount +;;; bignum-logbitp bignum-logcount ;;; These symbols define the interface to the compiler: ;;; bignum-type bignum-element-type bignum-index %allocate-bignum ;;; %bignum-length %bignum-set-length %bignum-ref %bignum-set @@ -755,7 +755,7 @@ ;; take up about the same space as corresponding fixnums, there ;; should be no way that we fall through to this case: any shift ;; right by a bignum should give zero. But let's check anyway: - (t (error "bignum overflow: can't shift right by ~S"))))) + (t (error "bignum overflow: can't shift right by ~S" count))))) (defun bignum-ashift-right-digits (bignum digits) (declare (type bignum-type bignum) @@ -812,7 +812,7 @@ (bignum-ashift-left-unaligned bignum digits n-bits res-len)))) ;; Left shift by a number too big to be represented as a fixnum ;; would exceed our memory capacity, since a fixnum is big enough - ;; index any array, including a bit array. + ;; to index any array, including a bit array. (error "can't represent result of left shift"))) (defun bignum-ashift-left-digits (bignum bignum-len digits) @@ -1009,7 +1009,7 @@ (t (round-up)))))) -;;;; integer length and logcount +;;;; integer length and logbitp/logcount (defun bignum-integer-length (bignum) (declare (type bignum-type bignum)) @@ -1021,6 +1021,17 @@ (+ (integer-length (%fixnum-digit-with-correct-sign digit)) (* len-1 digit-size)))) +(defun bignum-logbitp (index bignum) + (declare (type bignum-type bignum)) + (let ((len (%bignum-length bignum))) + (declare (type bignum-index len)) + (multiple-value-bind (word-index bit-index) + (floor index digit-size) + (if (>= word-index len) + (not (bignum-plus-p bignum)) + (not (zerop (logand (%bignum-ref bignum word-index) + (ash 1 bit-index)))))))) + (defun bignum-logcount (bignum) (declare (type bignum-type bignum)) (let* ((length (%bignum-length bignum))