X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fnumbers.lisp;h=751b6f2c40b683405e58cafee738d9f762ff3ef3;hb=6cc71ab8ffad49f43895ad0a1df6885c81876687;hp=1c27cd1e1efc184d3d4b8b26923d43932790a843;hpb=ca39b7d050ba21a6bf69d2d1030bda0ad7dd6b7b;p=sbcl.git diff --git a/src/code/numbers.lisp b/src/code/numbers.lisp index 1c27cd1..751b6f2 100644 --- a/src/code/numbers.lisp +++ b/src/code/numbers.lisp @@ -1008,8 +1008,9 @@ if INTEGER is negative." (etypecase integer (fixnum - (logcount (truly-the (integer 0 #.(max most-positive-fixnum - (lognot most-negative-fixnum))) + (logcount (truly-the (integer 0 + #.(max sb!xc:most-positive-fixnum + (lognot sb!xc:most-negative-fixnum))) (if (minusp (truly-the fixnum integer)) (lognot (truly-the fixnum integer)) integer)))) @@ -1024,7 +1025,12 @@ (defun logbitp (index integer) #!+sb-doc "Predicate returns T if bit index of integer is a 1." - (logbitp index integer)) + (number-dispatch ((index integer) (integer integer)) + ((fixnum fixnum) (if (> index #.(- sb!vm:n-word-bits sb!vm:n-lowtag-bits)) + (minusp integer) + (not (zerop (logand integer (ash 1 index)))))) + ((fixnum bignum) (bignum-logbitp index integer)) + ((bignum (foreach fixnum bignum)) (minusp integer)))) (defun ash (integer count) #!+sb-doc @@ -1263,7 +1269,20 @@ (defun two-arg-lcm (n m) (declare (integer n m)) - (* (truncate (max n m) (gcd n m)) (min n m))) + (if (or (zerop n) (zerop m)) + 0 + ;; KLUDGE: I'm going to assume that it was written this way + ;; originally for a reason. However, this is a somewhat + ;; complicated way of writing the algorithm in the CLHS page for + ;; LCM, and I don't know why. To be investigated. -- CSR, + ;; 2003-09-11 + (let ((m (abs m)) + (n (abs n))) + (multiple-value-bind (max min) + (if (> m n) + (values m n) + (values n m)) + (* (truncate max (gcd n m)) min))))) ;;; Do the GCD of two integer arguments. With fixnum arguments, we use the ;;; binary GCD algorithm from Knuth's seminumerical algorithms (slightly