X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fnumbers.lisp;h=31455e82de91b828e1be7147762c38fd79f8fb7b;hb=fb24d88c8f97f1b344addab398fc54f62d8aa4ce;hp=525beb7585b0dd9f31648bb51cf4896f7f3b533c;hpb=0c7a7f68e66276a3c780a01d55f086a6f0aac929;p=sbcl.git diff --git a/src/code/numbers.lisp b/src/code/numbers.lisp index 525beb7..31455e8 100644 --- a/src/code/numbers.lisp +++ b/src/code/numbers.lisp @@ -363,9 +363,9 @@ (,op (imagpart x) (imagpart y)))) (((foreach bignum fixnum ratio single-float double-float #!+long-float long-float) complex) - (complex (,op x (realpart y)) (,op (imagpart y)))) + (complex (,op x (realpart y)) (,op 0 (imagpart y)))) ((complex (or rational float)) - (complex (,op (realpart x) y) (imagpart x))) + (complex (,op (realpart x) y) (,op (imagpart x) 0))) (((foreach fixnum bignum) ratio) (let* ((dy (denominator y)) @@ -855,10 +855,10 @@ the first." ;; conversion. (multiple-value-bind (lo hi) (case '(dispatch-type y) - ('single-float + (single-float (values most-negative-exactly-single-float-fixnum most-positive-exactly-single-float-fixnum)) - ('double-float + (double-float (values most-negative-exactly-double-float-fixnum most-positive-exactly-double-float-fixnum))) (if (<= lo y hi) @@ -872,10 +872,10 @@ the first." ;; Likewise (multiple-value-bind (lo hi) (case '(dispatch-type x) - ('single-float + (single-float (values most-negative-exactly-single-float-fixnum most-positive-exactly-single-float-fixnum)) - ('double-float + (double-float (values most-negative-exactly-double-float-fixnum most-positive-exactly-double-float-fixnum))) (if (<= lo y hi) @@ -1384,29 +1384,31 @@ the first." ((fixnum bignum) (bignum-gcd (make-small-bignum u) v)))))) -;;; From discussion on comp.lang.lisp and Akira Kurihara. +;;;; from Robert Smith (defun isqrt (n) #!+sb-doc "Return the root of the nearest integer less than n which is a perfect square." - (declare (type unsigned-byte n) (values unsigned-byte)) - ;; Theoretically (> n 7), i.e., n-len-quarter > 0. - (if (and (fixnump n) (<= n 24)) - (cond ((> n 15) 4) - ((> n 8) 3) - ((> n 3) 2) - ((> n 0) 1) - (t 0)) - (let* ((n-len-quarter (ash (integer-length n) -2)) - (n-half (ash n (- (ash n-len-quarter 1)))) - (n-half-isqrt (isqrt n-half)) - (init-value (ash (1+ n-half-isqrt) n-len-quarter))) - (loop - (let ((iterated-value - (ash (+ init-value (truncate n init-value)) -1))) - (unless (< iterated-value init-value) - (return init-value)) - (setq init-value iterated-value)))))) + (declare (type unsigned-byte n)) + (cond + ((> n 24) + (let* ((n-fourth-size (ash (1- (integer-length n)) -2)) + (n-significant-half (ash n (- (ash n-fourth-size 1)))) + (n-significant-half-isqrt (isqrt n-significant-half)) + (zeroth-iteration (ash n-significant-half-isqrt n-fourth-size)) + (qr (multiple-value-list (floor n zeroth-iteration))) + (first-iteration (ash (+ zeroth-iteration (first qr)) -1))) + (cond ((oddp (first qr)) + first-iteration) + ((> (expt (- first-iteration zeroth-iteration) 2) (second qr)) + (1- first-iteration)) + (t + first-iteration)))) + ((> n 15) 4) + ((> n 8) 3) + ((> n 3) 2) + ((> n 0) 1) + ((= n 0) 0))) ;;;; miscellaneous number predicates