1 ;;;; code to implement bignum support
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!BIGNUM")
16 ;;; comments from CMU CL:
17 ;;; These symbols define the interface to the number code:
18 ;;; add-bignums multiply-bignums negate-bignum subtract-bignum
19 ;;; multiply-bignum-and-fixnum multiply-fixnums
20 ;;; bignum-ashift-right bignum-ashift-left bignum-gcd
21 ;;; bignum-to-float bignum-integer-length
22 ;;; bignum-logical-and bignum-logical-ior bignum-logical-xor
23 ;;; bignum-logical-not bignum-load-byte bignum-deposit-byte
24 ;;; bignum-truncate bignum-plus-p bignum-compare make-small-bignum
25 ;;; bignum-logbitp bignum-logcount
26 ;;; These symbols define the interface to the compiler:
27 ;;; bignum-type bignum-element-type bignum-index %allocate-bignum
28 ;;; %bignum-length %bignum-set-length %bignum-ref %bignum-set
29 ;;; %digit-0-or-plusp %add-with-carry %subtract-with-borrow
30 ;;; %multiply-and-add %multiply %lognot %logand %logior %logxor
31 ;;; %fixnum-to-digit %floor %fixnum-digit-with-correct-sign %ashl
32 ;;; %ashr %digit-logical-shift-right))
34 ;;; The following interfaces will either be assembler routines or code
35 ;;; sequences expanded into the code as basic bignum operations:
41 ;;; %BIGNUM-SET-LENGTH
42 ;;; %FIXNUM-DIGIT-WITH-CORRECT-SIGN
46 ;;; %BIGNUM-0-OR-PLUSP
47 ;;; %DIGIT-LOGICAL-SHIFT-RIGHT
48 ;;; General (May not exist when done due to sole use in %-routines.)
53 ;;; %SUBTRACT-WITH-BORROW
58 ;;; Shifting (in place)
59 ;;; %NORMALIZE-BIGNUM-BUFFER
60 ;;; GCD/Relational operators:
63 ;;; Relational operators:
72 ;;; Note: The floating routines know about the float representation.
75 ;;; There might be a problem with various LET's and parameters that take a
76 ;;; digit value. We need to write these so those things stay in machine
77 ;;; registers and number stack slots. I bind locals to these values, and I
78 ;;; use function on them -- ZEROP, ASH, etc.
81 ;;; In shifting and byte operations, I use masks and logical operations that
82 ;;; could result in intermediate bignums. This is hidden by the current system,
83 ;;; but I may need to write these in a way that keeps these masks and logical
84 ;;; operations from diving into the Lisp level bignum code.
88 ;;; logior, logxor, logand
89 ;;; depending on relationals, < (twice) and <= (twice)
90 ;;; or write compare thing (twice).
91 ;;; LDB on fixnum with bignum result.
92 ;;; DPB on fixnum with bignum result.
93 ;;; TRUNCATE returns zero or one as one value and fixnum or minus fixnum
94 ;;; for the other value when given (truncate fixnum bignum).
95 ;;; Returns (truncate bignum fixnum) otherwise.
97 ;;; subtraction (twice)
100 ;;; Write MASK-FIELD and DEPOSIT-FIELD in terms of logical operations.
102 ;;; IF (/ x y) with bignums:
103 ;;; do the truncate, and if rem is 0, return quotient.
106 ;;; "truncate" each by gcd, ignoring remainder 0.
107 ;;; form ratio of each result, bottom is positive.
109 ;;;; What's a bignum?
111 (defconstant digit-size sb!vm:n-word-bits)
113 (defconstant maximum-bignum-length (1- (ash 1 (- sb!vm:n-word-bits
114 sb!vm:n-widetag-bits))))
116 (defconstant all-ones-digit (1- (ash 1 sb!vm:n-word-bits)))
118 ;;;; internal inline routines
120 ;;; %ALLOCATE-BIGNUM must zero all elements.
121 (defun %allocate-bignum (length)
122 (declare (type bignum-index length))
123 (%allocate-bignum length))
125 ;;; Extract the length of the bignum.
126 (defun %bignum-length (bignum)
127 (declare (type bignum-type bignum))
128 (%bignum-length bignum))
130 ;;; %BIGNUM-REF needs to access bignums as obviously as possible, and it needs
131 ;;; to be able to return the digit somewhere no one looks for real objects.
132 (defun %bignum-ref (bignum i)
133 (declare (type bignum-type bignum)
134 (type bignum-index i))
135 (%bignum-ref bignum i))
136 (defun %bignum-set (bignum i value)
137 (declare (type bignum-type bignum)
138 (type bignum-index i)
139 (type bignum-element-type value))
140 (%bignum-set bignum i value))
142 ;;; Return T if digit is positive, or NIL if negative.
143 (defun %digit-0-or-plusp (digit)
144 (declare (type bignum-element-type digit))
145 (not (logbitp (1- digit-size) digit)))
147 #!-sb-fluid (declaim (inline %bignum-0-or-plusp))
148 (defun %bignum-0-or-plusp (bignum len)
149 (declare (type bignum-type bignum)
150 (type bignum-index len))
151 (%digit-0-or-plusp (%bignum-ref bignum (1- len))))
153 ;;; This should be in assembler, and should not cons intermediate
154 ;;; results. It returns a bignum digit and a carry resulting from adding
155 ;;; together a, b, and an incoming carry.
156 (defun %add-with-carry (a b carry)
157 (declare (type bignum-element-type a b)
158 (type (mod 2) carry))
159 (%add-with-carry a b carry))
161 ;;; This should be in assembler, and should not cons intermediate
162 ;;; results. It returns a bignum digit and a borrow resulting from
163 ;;; subtracting b from a, and subtracting a possible incoming borrow.
165 ;;; We really do: a - b - 1 + borrow, where borrow is either 0 or 1.
166 (defun %subtract-with-borrow (a b borrow)
167 (declare (type bignum-element-type a b)
168 (type (mod 2) borrow))
169 (%subtract-with-borrow a b borrow))
171 ;;; Multiply two digit-size numbers, returning a 2*digit-size result
172 ;;; split into two digit-size quantities.
173 (defun %multiply (x y)
174 (declare (type bignum-element-type x y))
177 ;;; This multiplies x-digit and y-digit, producing high and low digits
178 ;;; manifesting the result. Then it adds the low digit, res-digit, and
179 ;;; carry-in-digit. Any carries (note, you still have to add two digits
180 ;;; at a time possibly producing two carries) from adding these three
181 ;;; digits get added to the high digit from the multiply, producing the
182 ;;; next carry digit. Res-digit is optional since two uses of this
183 ;;; primitive multiplies a single digit bignum by a multiple digit
184 ;;; bignum, and in this situation there is no need for a result buffer
185 ;;; accumulating partial results which is where the res-digit comes
187 (defun %multiply-and-add (x-digit y-digit carry-in-digit
188 &optional (res-digit 0))
189 (declare (type bignum-element-type x-digit y-digit res-digit carry-in-digit))
190 (%multiply-and-add x-digit y-digit carry-in-digit res-digit))
192 (defun %lognot (digit)
193 (declare (type bignum-element-type digit))
196 ;;; Each of these does the digit-size unsigned op.
197 (declaim (inline %logand %logior %logxor))
199 (declare (type bignum-element-type a b))
202 (declare (type bignum-element-type a b))
205 (declare (type bignum-element-type a b))
208 ;;; This takes a fixnum and sets it up as an unsigned digit-size
210 (defun %fixnum-to-digit (x)
212 (logand x (1- (ash 1 digit-size))))
215 ;;; This takes three digits and returns the FLOOR'ed result of
216 ;;; dividing the first two as a 2*digit-size integer by the third.
218 ;;; Do weird LET and SETQ stuff to bamboozle the compiler into allowing
219 ;;; the %FLOOR transform to expand into pseudo-assembler for which the
220 ;;; compiler can later correctly allocate registers.
221 (defun %floor (a b c)
222 (let ((a a) (b b) (c c))
223 (declare (type bignum-element-type a b c))
227 ;;; Convert the digit to a regular integer assuming that the digit is signed.
228 (defun %fixnum-digit-with-correct-sign (digit)
229 (declare (type bignum-element-type digit))
230 (if (logbitp (1- digit-size) digit)
231 (logior digit (ash -1 digit-size))
234 ;;; Do an arithmetic shift right of data even though bignum-element-type is
236 (defun %ashr (data count)
237 (declare (type bignum-element-type data)
238 (type (mod #.sb!vm:n-word-bits) count))
241 ;;; This takes a digit-size quantity and shifts it to the left,
242 ;;; returning a digit-size quantity.
243 (defun %ashl (data count)
244 (declare (type bignum-element-type data)
245 (type (mod #.sb!vm:n-word-bits) count))
248 ;;; Do an unsigned (logical) right shift of a digit by Count.
249 (defun %digit-logical-shift-right (data count)
250 (declare (type bignum-element-type data)
251 (type (mod #.sb!vm:n-word-bits) count))
252 (%digit-logical-shift-right data count))
254 ;;; Change the length of bignum to be newlen. Newlen must be the same or
255 ;;; smaller than the old length, and any elements beyond newlen must be zeroed.
256 (defun %bignum-set-length (bignum newlen)
257 (declare (type bignum-type bignum)
258 (type bignum-index newlen))
259 (%bignum-set-length bignum newlen))
261 ;;; This returns 0 or "-1" depending on whether the bignum is positive. This
262 ;;; is suitable for infinite sign extension to complete additions,
263 ;;; subtractions, negations, etc. This cannot return a -1 represented as
264 ;;; a negative fixnum since it would then have to low zeros.
265 #!-sb-fluid (declaim (inline %sign-digit))
266 (defun %sign-digit (bignum len)
267 (declare (type bignum-type bignum)
268 (type bignum-index len))
269 (%ashr (%bignum-ref bignum (1- len)) (1- digit-size)))
271 ;;; These take two digit-size quantities and compare or contrast them
272 ;;; without wasting time with incorrect type checking.
273 (declaim (inline %digit-compare %digit-greater))
274 (defun %digit-compare (x y)
276 (defun %digit-greater (x y)
279 (declaim (optimize (speed 3) (safety 0)))
283 (defun add-bignums (a b)
284 (declare (type bignum-type a b))
285 (let ((len-a (%bignum-length a))
286 (len-b (%bignum-length b)))
287 (declare (type bignum-index len-a len-b))
288 (multiple-value-bind (a len-a b len-b)
290 (values a len-a b len-b)
291 (values b len-b a len-a))
292 (declare (type bignum-type a b)
293 (type bignum-index len-a len-b))
294 (let* ((len-res (1+ len-a))
295 (res (%allocate-bignum len-res))
297 (declare (type bignum-index len-res)
298 (type bignum-type res)
299 (type (mod 2) carry))
301 (declare (type bignum-index i))
302 (multiple-value-bind (v k)
303 (%add-with-carry (%bignum-ref a i) (%bignum-ref b i) carry)
304 (declare (type bignum-element-type v)
306 (setf (%bignum-ref res i) v)
309 (finish-add a res carry (%sign-digit b len-b) len-b len-a)
310 (setf (%bignum-ref res len-a)
311 (%add-with-carry (%sign-digit a len-a)
312 (%sign-digit b len-b)
314 (%normalize-bignum res len-res)))))
316 ;;; This takes the longer of two bignums and propagates the carry through its
317 ;;; remaining high order digits.
318 (defun finish-add (a res carry sign-digit-b start end)
319 (declare (type bignum-type a res)
321 (type bignum-element-type sign-digit-b)
322 (type bignum-index start end))
323 (do ((i start (1+ i)))
325 (setf (%bignum-ref res end)
326 (%add-with-carry (%sign-digit a end) sign-digit-b carry)))
327 (declare (type bignum-index i))
328 (multiple-value-bind (v k)
329 (%add-with-carry (%bignum-ref a i) sign-digit-b carry)
330 (setf (%bignum-ref res i) v)
336 (eval-when (:compile-toplevel :execute)
338 ;;; This subtracts b from a plugging result into res. Return-fun is the
339 ;;; function to call that fixes up the result returning any useful values, such
340 ;;; as the result. This macro may evaluate its arguments more than once.
341 (sb!xc:defmacro subtract-bignum-loop (a len-a b len-b res len-res return-fun)
342 (with-unique-names (borrow a-digit a-sign b-digit b-sign i v k)
344 (,a-sign (%sign-digit ,a ,len-a))
345 (,b-sign (%sign-digit ,b ,len-b)))
346 (declare (type bignum-element-type ,a-sign ,b-sign))
347 (dotimes (,i ,len-res)
348 (declare (type bignum-index ,i))
349 (let ((,a-digit (if (< ,i ,len-a) (%bignum-ref ,a ,i) ,a-sign))
350 (,b-digit (if (< ,i ,len-b) (%bignum-ref ,b ,i) ,b-sign)))
351 (declare (type bignum-element-type ,a-digit ,b-digit))
352 (multiple-value-bind (,v ,k)
353 (%subtract-with-borrow ,a-digit ,b-digit ,borrow)
354 (setf (%bignum-ref ,res ,i) ,v)
356 (,return-fun ,res ,len-res))))
360 (defun subtract-bignum (a b)
361 (declare (type bignum-type a b))
362 (let* ((len-a (%bignum-length a))
363 (len-b (%bignum-length b))
364 (len-res (1+ (max len-a len-b)))
365 (res (%allocate-bignum len-res)))
366 (declare (type bignum-index len-a len-b len-res)) ;Test len-res for bounds?
367 (subtract-bignum-loop a len-a b len-b res len-res %normalize-bignum)))
369 ;;; Operations requiring a subtraction without the overhead of intermediate
370 ;;; results, such as GCD, use this. It assumes Result is big enough for the
372 (defun subtract-bignum-buffers-with-len (a len-a b len-b result len-res)
373 (declare (type bignum-type a b result)
374 (type bignum-index len-a len-b len-res))
375 (subtract-bignum-loop a len-a b len-b result len-res
376 %normalize-bignum-buffer))
378 (defun subtract-bignum-buffers (a len-a b len-b result)
379 (declare (type bignum-type a b result)
380 (type bignum-index len-a len-b))
381 (subtract-bignum-loop a len-a b len-b result (max len-a len-b)
382 %normalize-bignum-buffer))
386 (defun multiply-bignums (a b)
387 (declare (type bignum-type a b))
388 (let* ((a-plusp (%bignum-0-or-plusp a (%bignum-length a)))
389 (b-plusp (%bignum-0-or-plusp b (%bignum-length b)))
390 (a (if a-plusp a (negate-bignum a)))
391 (b (if b-plusp b (negate-bignum b)))
392 (len-a (%bignum-length a))
393 (len-b (%bignum-length b))
394 (len-res (+ len-a len-b))
395 (res (%allocate-bignum len-res))
396 (negate-res (not (eq a-plusp b-plusp))))
397 (declare (type bignum-index len-a len-b len-res))
399 (declare (type bignum-index i))
400 (let ((carry-digit 0)
401 (x (%bignum-ref a i))
403 (declare (type bignum-index k)
404 (type bignum-element-type carry-digit x))
406 (multiple-value-bind (big-carry res-digit)
411 (declare (type bignum-element-type big-carry res-digit))
412 (setf (%bignum-ref res k) res-digit)
413 (setf carry-digit big-carry)
415 (setf (%bignum-ref res k) carry-digit)))
416 (when negate-res (negate-bignum-in-place res))
417 (%normalize-bignum res len-res)))
419 (defun multiply-bignum-and-fixnum (bignum fixnum)
420 (declare (type bignum-type bignum) (type fixnum fixnum))
421 (let* ((bignum-plus-p (%bignum-0-or-plusp bignum (%bignum-length bignum)))
422 (fixnum-plus-p (not (minusp fixnum)))
423 (bignum (if bignum-plus-p bignum (negate-bignum bignum)))
424 (bignum-len (%bignum-length bignum))
425 (fixnum (if fixnum-plus-p fixnum (- fixnum)))
426 (result (%allocate-bignum (1+ bignum-len)))
428 (declare (type bignum-type bignum result)
429 (type bignum-index bignum-len)
430 (type bignum-element-type fixnum carry-digit))
431 (dotimes (index bignum-len)
432 (declare (type bignum-index index))
433 (multiple-value-bind (next-digit low)
434 (%multiply-and-add (%bignum-ref bignum index) fixnum carry-digit)
435 (declare (type bignum-element-type next-digit low))
436 (setf carry-digit next-digit)
437 (setf (%bignum-ref result index) low)))
438 (setf (%bignum-ref result bignum-len) carry-digit)
439 (unless (eq bignum-plus-p fixnum-plus-p)
440 (negate-bignum-in-place result))
441 (%normalize-bignum result (1+ bignum-len))))
443 (defun multiply-fixnums (a b)
444 (declare (fixnum a b))
445 (let* ((a-minusp (minusp a))
446 (b-minusp (minusp b)))
447 (multiple-value-bind (high low)
448 (%multiply (if a-minusp (- a) a)
449 (if b-minusp (- b) b))
450 (declare (type bignum-element-type high low))
451 (if (and (zerop high)
452 (%digit-0-or-plusp low))
453 (let ((low (sb!ext:truly-the (unsigned-byte #.(1- sb!vm:n-word-bits))
454 (%fixnum-digit-with-correct-sign low))))
455 (if (eq a-minusp b-minusp)
458 (let ((res (%allocate-bignum 2)))
459 (%bignum-set res 0 low)
460 (%bignum-set res 1 high)
461 (unless (eq a-minusp b-minusp) (negate-bignum-in-place res))
462 (%normalize-bignum res 2))))))
464 ;;;; BIGNUM-REPLACE and WITH-BIGNUM-BUFFERS
466 (eval-when (:compile-toplevel :execute)
468 (sb!xc:defmacro bignum-replace (dest
476 (sb!int:once-only ((n-dest dest)
478 (with-unique-names (n-start1 n-end1 n-start2 n-end2 i1 i2)
479 (let ((end1 (or end1 `(%bignum-length ,n-dest)))
480 (end2 (or end2 `(%bignum-length ,n-src))))
482 `(let ((,n-start1 ,start1)
484 (do ((,i1 (1- ,end1) (1- ,i1))
485 (,i2 (1- ,end2) (1- ,i2)))
486 ((or (< ,i1 ,n-start1) (< ,i2 ,n-start2)))
487 (declare (fixnum ,i1 ,i2))
488 (%bignum-set ,n-dest ,i1 (%bignum-ref ,n-src ,i2))))
489 (if (eql start1 start2)
490 `(let ((,n-end1 (min ,end1 ,end2)))
491 (do ((,i1 ,start1 (1+ ,i1)))
493 (declare (type bignum-index ,i1))
494 (%bignum-set ,n-dest ,i1 (%bignum-ref ,n-src ,i1))))
495 `(let ((,n-end1 ,end1)
497 (do ((,i1 ,start1 (1+ ,i1))
498 (,i2 ,start2 (1+ ,i2)))
499 ((or (>= ,i1 ,n-end1) (>= ,i2 ,n-end2)))
500 (declare (type bignum-index ,i1 ,i2))
501 (%bignum-set ,n-dest ,i1 (%bignum-ref ,n-src ,i2))))))))))
503 (sb!xc:defmacro with-bignum-buffers (specs &body body)
505 "WITH-BIGNUM-BUFFERS ({(var size [init])}*) Form*"
506 (sb!int:collect ((binds)
509 (let ((name (first spec))
510 (size (second spec)))
511 (binds `(,name (%allocate-bignum ,size)))
512 (let ((init (third spec)))
514 (inits `(bignum-replace ,name ,init))))))
523 (eval-when (:compile-toplevel :load-toplevel :execute)
524 ;; The asserts in the GCD implementation are way too expensive to
525 ;; check in normal use, and are disabled here.
526 (sb!xc:defmacro gcd-assert (&rest args)
529 ;; We'll be doing a lot of modular arithmetic.
530 (sb!xc:defmacro modularly (form)
531 `(logand all-ones-digit ,form)))
533 ;;; I'm not sure why I need this FTYPE declaration. Compiled by the
534 ;;; target compiler, it can deduce the return type fine, but without
535 ;;; it, we pay a heavy price in BIGNUM-GCD when compiled by the
536 ;;; cross-compiler. -- CSR, 2004-07-19
537 (declaim (ftype (sfunction (bignum-type bignum-index bignum-type bignum-index)
538 (and unsigned-byte fixnum))
539 bignum-factors-of-two))
540 (defun bignum-factors-of-two (a len-a b len-b)
541 (declare (type bignum-index len-a len-b) (type bignum-type a b))
543 (end (min len-a len-b)))
544 ((= i end) (error "Unexpected zero bignums?"))
545 (declare (type bignum-index i end))
546 (let ((or-digits (%logior (%bignum-ref a i) (%bignum-ref b i))))
547 (unless (zerop or-digits)
548 (return (do ((j 0 (1+ j))
549 (or-digits or-digits (%ashr or-digits 1)))
550 ((oddp or-digits) (+ (* i digit-size) j))
551 (declare (type (mod #.sb!vm:n-word-bits) j))))))))
553 ;;; Multiply a bignum buffer with a fixnum or a digit, storing the
554 ;;; result in another bignum buffer, and without using any
555 ;;; temporaries. Inlined to avoid boxing smallnum if it's actually a
556 ;;; digit. Needed by GCD, should possibly OAOO with
557 ;;; MULTIPLY-BIGNUM-AND-FIXNUM.
558 (declaim (inline multiply-bignum-buffer-and-smallnum-to-buffer))
559 (defun multiply-bignum-buffer-and-smallnum-to-buffer (bignum bignum-len
561 (declare (type bignum-type bignum))
562 (let* ((bignum-plus-p (%bignum-0-or-plusp bignum bignum-len))
563 (smallnum-plus-p (not (minusp smallnum)))
564 (smallnum (if smallnum-plus-p smallnum (- smallnum)))
566 (declare (type bignum-type bignum res)
567 (type bignum-index bignum-len)
568 (type bignum-element-type smallnum carry-digit))
569 (unless bignum-plus-p
570 (negate-bignum-buffer-in-place bignum bignum-len))
571 (dotimes (index bignum-len)
572 (declare (type bignum-index index))
573 (multiple-value-bind (next-digit low)
574 (%multiply-and-add (%bignum-ref bignum index)
577 (declare (type bignum-element-type next-digit low))
578 (setf carry-digit next-digit)
579 (setf (%bignum-ref res index) low)))
580 (setf (%bignum-ref res bignum-len) carry-digit)
581 (unless bignum-plus-p
582 (negate-bignum-buffer-in-place bignum bignum-len))
583 (let ((res-len (%normalize-bignum-buffer res (1+ bignum-len))))
584 (unless (eq bignum-plus-p smallnum-plus-p)
585 (negate-bignum-buffer-in-place res res-len))
588 ;;; Given U and V, return U / V mod 2^32. Implements the algorithm in the
589 ;;; paper, but uses some clever bit-twiddling nicked from Nickle to do it.
590 (declaim (inline bmod))
592 (let ((ud (%bignum-ref u 0))
593 (vd (%bignum-ref v 0))
597 (declare (type (unsigned-byte #.sb!vm:n-word-bits) ud vd umask imask m))
598 (dotimes (i digit-size)
599 (setf umask (logior umask imask))
600 (when (logtest ud umask)
601 (setf ud (modularly (- ud vd)))
602 (setf m (modularly (logior m imask))))
603 (setf imask (modularly (ash imask 1)))
604 (setf vd (modularly (ash vd 1))))
607 (defun dmod (u u-len v v-len tmp1)
608 (loop while (> (bignum-buffer-integer-length u u-len)
609 (+ (bignum-buffer-integer-length v v-len)
612 (unless (zerop (%bignum-ref u 0))
613 (let* ((bmod (bmod u v))
614 (tmp1-len (multiply-bignum-buffer-and-smallnum-to-buffer v v-len
617 (setf u-len (subtract-bignum-buffers u u-len
620 (bignum-abs-buffer u u-len)))
621 (gcd-assert (zerop (%bignum-ref u 0)))
622 (setf u-len (bignum-buffer-ashift-right u u-len digit-size)))
623 (let* ((d (+ 1 (- (bignum-buffer-integer-length u u-len)
624 (bignum-buffer-integer-length v v-len))))
626 (declare (type (unsigned-byte #.(integer-length #.sb!vm:n-word-bits)) d)
627 (type (unsigned-byte #.sb!vm:n-word-bits) n))
628 (gcd-assert (>= d 0))
629 (when (logtest (%bignum-ref u 0) n)
631 (multiply-bignum-buffer-and-smallnum-to-buffer v v-len
635 (setf u-len (subtract-bignum-buffers u u-len
638 (bignum-abs-buffer u u-len)))
641 (defconstant lower-ones-digit (1- (ash 1 (truncate sb!vm:n-word-bits 2))))
643 ;;; Find D and N such that (LOGAND ALL-ONES-DIGIT (- (* D X) (* N Y))) is 0,
644 ;;; (< 0 N LOWER-ONES-DIGIT) and (< 0 (ABS D) LOWER-ONES-DIGIT).
645 (defun reduced-ratio-mod (x y)
646 (let* ((c (bmod x y))
649 (n2 (modularly (1+ (modularly (lognot n1)))))
651 (declare (type (unsigned-byte #.sb!vm:n-word-bits) n1 d1 n2 d2))
652 (loop while (> n2 (expt 2 (truncate digit-size 2))) do
653 (loop for i of-type (mod #.sb!vm:n-word-bits)
654 downfrom (- (integer-length n1) (integer-length n2))
656 (when (>= n1 (modularly (ash n2 i)))
657 (psetf n1 (modularly (- n1 (modularly (ash n2 i))))
658 d1 (modularly (- d1 (modularly (ash d2 i)))))))
663 (values n2 (if (>= d2 (expt 2 (1- digit-size)))
664 (lognot (logand most-positive-fixnum (lognot d2)))
665 (logand lower-ones-digit d2)))))
668 (defun copy-bignum (a &optional (len (%bignum-length a)))
669 (let ((b (%allocate-bignum len)))
671 (%bignum-set-length b len)
674 ;;; Allocate a single word bignum that holds fixnum. This is useful when
675 ;;; we are trying to mix fixnum and bignum operands.
676 #!-sb-fluid (declaim (inline make-small-bignum))
677 (defun make-small-bignum (fixnum)
678 (let ((res (%allocate-bignum 1)))
679 (setf (%bignum-ref res 0) (%fixnum-to-digit fixnum))
682 ;; When the larger number is less than this many bignum digits long, revert
684 (defparameter *accelerated-gcd-cutoff* 3)
686 ;;; Alternate between k-ary reduction with the help of
687 ;;; REDUCED-RATIO-MOD and digit modulus reduction via DMOD. Once the
688 ;;; arguments get small enough, drop through to BIGNUM-MOD-GCD (since
689 ;;; k-ary reduction can introduce spurious factors, which need to be
690 ;;; filtered out). Reference: Kenneth Weber, "The accelerated integer
691 ;;; GCD algorithm", ACM Transactions on Mathematical Software, volume
692 ;;; 21, number 1, March 1995, epp. 111-122.
693 (defun bignum-gcd (u0 v0)
694 (declare (type bignum-type u0 v0))
695 (let* ((u1 (if (%bignum-0-or-plusp u0 (%bignum-length u0))
697 (negate-bignum u0 nil)))
698 (v1 (if (%bignum-0-or-plusp v0 (%bignum-length v0))
700 (negate-bignum v0 nil))))
702 (return-from bignum-gcd u1))
705 (let ((n (mod v1 u1)))
706 (setf v1 (if (fixnump n)
707 (make-small-bignum n)
709 (if (and (= 1 (%bignum-length v1))
710 (zerop (%bignum-ref v1 0)))
711 (return-from bignum-gcd (%normalize-bignum u1
712 (%bignum-length u1))))
713 (let* ((buffer-len (+ 2 (%bignum-length u1)))
714 (u (%allocate-bignum buffer-len))
715 (u-len (%bignum-length u1))
716 (v (%allocate-bignum buffer-len))
717 (v-len (%bignum-length v1))
718 (tmp1 (%allocate-bignum buffer-len))
720 (tmp2 (%allocate-bignum buffer-len))
723 (bignum-factors-of-two u1 (%bignum-length u1)
724 v1 (%bignum-length v1))))
725 (declare (type (or null bignum-index)
726 buffer-len u-len v-len tmp1-len tmp2-len))
727 (bignum-replace u u1)
728 (bignum-replace v v1)
730 (make-gcd-bignum-odd u
731 (bignum-buffer-ashift-right u u-len
734 (make-gcd-bignum-odd v
735 (bignum-buffer-ashift-right v v-len
737 (loop until (or (< u-len *accelerated-gcd-cutoff*)
741 (zerop (%bignum-ref v 0))))
743 (gcd-assert (= buffer-len (%bignum-length u)
745 (%bignum-length tmp1)
746 (%bignum-length tmp2)))
747 (if (> (bignum-buffer-integer-length u u-len)
748 (+ #.(truncate sb!vm:n-word-bits 4)
749 (bignum-buffer-integer-length v v-len)))
750 (setf u-len (dmod u u-len
753 (multiple-value-bind (n d) (reduced-ratio-mod u v)
755 (multiply-bignum-buffer-and-smallnum-to-buffer v v-len
758 (multiply-bignum-buffer-and-smallnum-to-buffer u u-len
760 (gcd-assert (= (copy-bignum tmp2 tmp2-len)
761 (* (copy-bignum u u-len) d)))
762 (gcd-assert (= (copy-bignum tmp1 tmp1-len)
763 (* (copy-bignum v v-len) n)))
765 (subtract-bignum-buffers-with-len tmp1 tmp1-len
770 (gcd-assert (or (zerop (- (copy-bignum tmp1 tmp1-len)
771 (copy-bignum tmp2 tmp2-len)))
772 (= (copy-bignum u u-len)
773 (- (copy-bignum tmp1 tmp1-len)
774 (copy-bignum tmp2 tmp2-len)))))
775 (bignum-abs-buffer u u-len)
776 (gcd-assert (zerop (modularly u)))))
777 (setf u-len (make-gcd-bignum-odd u u-len))
779 (rotatef u-len v-len))
780 (bignum-abs-buffer u u-len)
781 (setf u (copy-bignum u u-len))
782 (let ((n (bignum-mod-gcd v1 u)))
783 (ash (bignum-mod-gcd u1 (if (fixnump n)
784 (make-small-bignum n)
788 (defun bignum-mod-gcd (a b)
789 (declare (type bignum-type a b))
792 ;; While the length difference of A and B is sufficiently large,
793 ;; reduce using MOD (slowish, but it should equalize the sizes of
794 ;; A and B pretty quickly). After that, use the binary GCD
795 ;; algorithm to handle the rest.
796 (loop until (and (= (%bignum-length b) 1) (zerop (%bignum-ref b 0))) do
797 (when (<= (%bignum-length a) (1+ (%bignum-length b)))
798 (return-from bignum-mod-gcd (bignum-binary-gcd a b)))
799 (let ((rem (mod a b)))
801 (setf a (make-small-bignum rem))
804 (if (= (%bignum-length a) 1)
805 (%normalize-bignum a 1)
808 (defun bignum-binary-gcd (a b)
809 (declare (type bignum-type a b))
810 (let* ((len-a (%bignum-length a))
811 (len-b (%bignum-length b)))
812 (declare (type bignum-index len-a len-b))
813 (with-bignum-buffers ((a-buffer len-a a)
815 (res-buffer (max len-a len-b)))
816 (let* ((factors-of-two
817 (bignum-factors-of-two a-buffer len-a
819 (len-a (make-gcd-bignum-odd
821 (bignum-buffer-ashift-right a-buffer len-a
823 (len-b (make-gcd-bignum-odd
825 (bignum-buffer-ashift-right b-buffer len-b
827 (declare (type bignum-index len-a len-b))
834 (multiple-value-bind (u v len-v r len-r)
835 (bignum-gcd-order-and-subtract x len-x y len-y z)
836 (declare (type bignum-index len-v len-r))
837 (when (and (= len-r 1) (zerop (%bignum-ref r 0)))
838 (if (zerop factors-of-two)
839 (let ((ret (%allocate-bignum len-v)))
841 (setf (%bignum-ref ret i) (%bignum-ref v i)))
842 (return (%normalize-bignum ret len-v)))
843 (return (bignum-ashift-left v factors-of-two len-v))))
844 (setf x v len-x len-v)
845 (setf y r len-y (make-gcd-bignum-odd r len-r))
848 (defun bignum-gcd-order-and-subtract (a len-a b len-b res)
849 (declare (type bignum-index len-a len-b) (type bignum-type a b))
850 (cond ((= len-a len-b)
851 (do ((i (1- len-a) (1- i)))
853 (setf (%bignum-ref res 0) 0)
854 (values a b len-b res 1))
855 (let ((a-digit (%bignum-ref a i))
856 (b-digit (%bignum-ref b i)))
857 (cond ((%digit-compare a-digit b-digit))
858 ((%digit-greater a-digit b-digit)
860 (values a b len-b res
861 (subtract-bignum-buffers a len-a b len-b
865 (values b a len-a res
866 (subtract-bignum-buffers b len-b
870 (values a b len-b res
871 (subtract-bignum-buffers a len-a b len-b res)))
873 (values b a len-a res
874 (subtract-bignum-buffers b len-b a len-a res)))))
876 (defun make-gcd-bignum-odd (a len-a)
877 (declare (type bignum-type a) (type bignum-index len-a))
878 (dotimes (index len-a)
879 (declare (type bignum-index index))
880 (do ((digit (%bignum-ref a index) (%ashr digit 1))
881 (increment 0 (1+ increment)))
883 (declare (type (mod #.sb!vm:n-word-bits) increment))
885 (return-from make-gcd-bignum-odd
886 (bignum-buffer-ashift-right a len-a
887 (+ (* index digit-size)
893 (eval-when (:compile-toplevel :execute)
895 ;;; This negates bignum-len digits of bignum, storing the resulting digits into
896 ;;; result (possibly EQ to bignum) and returning whatever end-carry there is.
897 (sb!xc:defmacro bignum-negate-loop
898 (bignum bignum-len &optional (result nil resultp))
899 (with-unique-names (carry end value last)
900 `(let* (,@(if (not resultp) `(,last))
902 (multiple-value-bind (,value ,carry)
903 (%add-with-carry (%lognot (%bignum-ref ,bignum 0)) 1 0)
905 `(setf (%bignum-ref ,result 0) ,value)
906 `(setf ,last ,value))
910 (declare (type bit ,carry)
911 (type bignum-index i ,end))
913 (when (= i ,end) (return))
914 (multiple-value-bind (,value temp)
915 (%add-with-carry (%lognot (%bignum-ref ,bignum i)) 0 ,carry)
917 `(setf (%bignum-ref ,result i) ,value)
918 `(setf ,last ,value))
921 ,(if resultp carry `(values ,carry ,last)))))
925 ;;; Fully-normalize is an internal optional. It cause this to always return
926 ;;; a bignum, without any extraneous digits, and it never returns a fixnum.
927 (defun negate-bignum (x &optional (fully-normalize t))
928 (declare (type bignum-type x))
929 (let* ((len-x (%bignum-length x))
931 (res (%allocate-bignum len-res)))
932 (declare (type bignum-index len-x len-res)) ;Test len-res for range?
933 (let ((carry (bignum-negate-loop x len-x res)))
934 (setf (%bignum-ref res len-x)
935 (%add-with-carry (%lognot (%sign-digit x len-x)) 0 carry)))
937 (%normalize-bignum res len-res)
938 (%mostly-normalize-bignum res len-res))))
940 ;;; This assumes bignum is positive; that is, the result of negating it will
941 ;;; stay in the provided allocated bignum.
942 (defun negate-bignum-buffer-in-place (bignum bignum-len)
943 (bignum-negate-loop bignum bignum-len bignum)
946 (defun negate-bignum-in-place (bignum)
947 (declare (inline negate-bignum-buffer-in-place))
948 (negate-bignum-buffer-in-place bignum (%bignum-length bignum)))
950 (defun bignum-abs-buffer (bignum len)
951 (unless (%bignum-0-or-plusp bignum len)
952 (negate-bignum-buffer-in-place bignum len)))
956 (eval-when (:compile-toplevel :execute)
958 ;;; This macro is used by BIGNUM-ASHIFT-RIGHT, BIGNUM-BUFFER-ASHIFT-RIGHT, and
959 ;;; BIGNUM-LDB-BIGNUM-RES. They supply a termination form that references
960 ;;; locals established by this form. Source is the source bignum. Start-digit
961 ;;; is the first digit in source from which we pull bits. Start-pos is the
962 ;;; first bit we want. Res-len-form is the form that computes the length of
963 ;;; the resulting bignum. Termination is a DO termination form with a test and
964 ;;; body. When result is supplied, it is the variable to which this binds a
965 ;;; newly allocated bignum.
967 ;;; Given start-pos, 1-31 inclusively, of shift, we form the j'th resulting
968 ;;; digit from high bits of the i'th source digit and the start-pos number of
969 ;;; bits from the i+1'th source digit.
970 (sb!xc:defmacro shift-right-unaligned (source
976 `(let* ((high-bits-in-first-digit (- digit-size ,start-pos))
977 (res-len ,res-len-form)
978 (res-len-1 (1- res-len))
979 ,@(if result `((,result (%allocate-bignum res-len)))))
980 (declare (type bignum-index res-len res-len-1))
981 (do ((i ,start-digit (1+ i))
984 (declare (type bignum-index i j))
985 (setf (%bignum-ref ,(if result result source) j)
986 (%logior (%digit-logical-shift-right (%bignum-ref ,source i)
988 (%ashl (%bignum-ref ,source (1+ i))
989 high-bits-in-first-digit))))))
993 ;;; First compute the number of whole digits to shift, shifting them by
994 ;;; skipping them when we start to pick up bits, and the number of bits to
995 ;;; shift the remaining digits into place. If the number of digits is greater
996 ;;; than the length of the bignum, then the result is either 0 or -1. If we
997 ;;; shift on a digit boundary (that is, n-bits is zero), then we just copy
998 ;;; digits. The last branch handles the general case which uses a macro that a
999 ;;; couple other routines use. The fifth argument to the macro references
1000 ;;; locals established by the macro.
1001 (defun bignum-ashift-right (bignum count)
1002 (declare (type bignum-type bignum)
1003 (type unsigned-byte count))
1004 (let ((bignum-len (%bignum-length bignum)))
1005 (declare (type bignum-index bignum-len))
1006 (cond ((fixnump count)
1007 (multiple-value-bind (digits n-bits) (truncate count digit-size)
1008 (declare (type bignum-index digits))
1010 ((>= digits bignum-len)
1011 (if (%bignum-0-or-plusp bignum bignum-len) 0 -1))
1013 (bignum-ashift-right-digits bignum digits))
1015 (shift-right-unaligned bignum digits n-bits (- bignum-len digits)
1017 (setf (%bignum-ref res j)
1018 (%ashr (%bignum-ref bignum i) n-bits))
1019 (%normalize-bignum res res-len))
1021 ((> count bignum-len)
1022 (if (%bignum-0-or-plusp bignum bignum-len) 0 -1))
1023 ;; Since a FIXNUM should be big enough to address anything in
1024 ;; memory, including arrays of bits, and since arrays of bits
1025 ;; take up about the same space as corresponding fixnums, there
1026 ;; should be no way that we fall through to this case: any shift
1027 ;; right by a bignum should give zero. But let's check anyway:
1028 (t (error "bignum overflow: can't shift right by ~S" count)))))
1030 (defun bignum-ashift-right-digits (bignum digits)
1031 (declare (type bignum-type bignum)
1032 (type bignum-index digits))
1033 (let* ((res-len (- (%bignum-length bignum) digits))
1034 (res (%allocate-bignum res-len)))
1035 (declare (type bignum-index res-len)
1036 (type bignum-type res))
1037 (bignum-replace res bignum :start2 digits)
1038 (%normalize-bignum res res-len)))
1040 ;;; GCD uses this for an in-place shifting operation. This is different enough
1041 ;;; from BIGNUM-ASHIFT-RIGHT that it isn't worth folding the bodies into a
1042 ;;; macro, but they share the basic algorithm. This routine foregoes a first
1043 ;;; test for digits being greater than or equal to bignum-len since that will
1044 ;;; never happen for its uses in GCD. We did fold the last branch into a macro
1045 ;;; since it was duplicated a few times, and the fifth argument to it
1046 ;;; references locals established by the macro.
1047 (defun bignum-buffer-ashift-right (bignum bignum-len x)
1048 (declare (type bignum-index bignum-len) (fixnum x))
1049 (multiple-value-bind (digits n-bits) (truncate x digit-size)
1050 (declare (type bignum-index digits))
1053 (let ((new-end (- bignum-len digits)))
1054 (bignum-replace bignum bignum :end1 new-end :start2 digits
1056 (%normalize-bignum-buffer bignum new-end)))
1058 (shift-right-unaligned bignum digits n-bits (- bignum-len digits)
1060 (setf (%bignum-ref bignum j)
1061 (%ashr (%bignum-ref bignum i) n-bits))
1062 (%normalize-bignum-buffer bignum res-len)))))))
1064 ;;; This handles shifting a bignum buffer to provide fresh bignum data for some
1065 ;;; internal routines. We know bignum is safe when called with bignum-len.
1066 ;;; First we compute the number of whole digits to shift, shifting them
1067 ;;; starting to store farther along the result bignum. If we shift on a digit
1068 ;;; boundary (that is, n-bits is zero), then we just copy digits. The last
1069 ;;; branch handles the general case.
1070 (defun bignum-ashift-left (bignum x &optional bignum-len)
1071 (declare (type bignum-type bignum)
1072 (type unsigned-byte x)
1073 (type (or null bignum-index) bignum-len))
1075 (multiple-value-bind (digits n-bits) (truncate x digit-size)
1076 (let* ((bignum-len (or bignum-len (%bignum-length bignum)))
1077 (res-len (+ digits bignum-len 1)))
1078 (when (> res-len maximum-bignum-length)
1079 (error "can't represent result of left shift"))
1081 (bignum-ashift-left-digits bignum bignum-len digits)
1082 (bignum-ashift-left-unaligned bignum digits n-bits res-len))))
1083 ;; Left shift by a number too big to be represented as a fixnum
1084 ;; would exceed our memory capacity, since a fixnum is big enough
1085 ;; to index any array, including a bit array.
1086 (error "can't represent result of left shift")))
1088 (defun bignum-ashift-left-digits (bignum bignum-len digits)
1089 (declare (type bignum-index bignum-len digits))
1090 (let* ((res-len (+ bignum-len digits))
1091 (res (%allocate-bignum res-len)))
1092 (declare (type bignum-index res-len))
1093 (bignum-replace res bignum :start1 digits :end1 res-len :end2 bignum-len
1097 ;;; BIGNUM-TRUNCATE uses this to store into a bignum buffer by supplying res.
1098 ;;; When res comes in non-nil, then this foregoes allocating a result, and it
1099 ;;; normalizes the buffer instead of the would-be allocated result.
1101 ;;; We start storing into one digit higher than digits, storing a whole result
1102 ;;; digit from parts of two contiguous digits from bignum. When the loop
1103 ;;; finishes, we store the remaining bits from bignum's first digit in the
1104 ;;; first non-zero result digit, digits. We also grab some left over high
1105 ;;; bits from the last digit of bignum.
1106 (defun bignum-ashift-left-unaligned (bignum digits n-bits res-len
1107 &optional (res nil resp))
1108 (declare (type bignum-index digits res-len)
1109 (type (mod #.digit-size) n-bits))
1110 (let* ((remaining-bits (- digit-size n-bits))
1111 (res-len-1 (1- res-len))
1112 (res (or res (%allocate-bignum res-len))))
1113 (declare (type bignum-index res-len res-len-1))
1115 (j (1+ digits) (1+ j)))
1117 (setf (%bignum-ref res digits)
1118 (%ashl (%bignum-ref bignum 0) n-bits))
1119 (setf (%bignum-ref res j)
1120 (%ashr (%bignum-ref bignum i) remaining-bits))
1122 (%normalize-bignum-buffer res res-len)
1123 (%normalize-bignum res res-len)))
1124 (declare (type bignum-index i j))
1125 (setf (%bignum-ref res j)
1126 (%logior (%digit-logical-shift-right (%bignum-ref bignum i)
1128 (%ashl (%bignum-ref bignum (1+ i)) n-bits))))))
1130 ;;;; relational operators
1132 ;;; Return T iff bignum is positive.
1133 (defun bignum-plus-p (bignum)
1134 (declare (type bignum-type bignum))
1135 (%bignum-0-or-plusp bignum (%bignum-length bignum)))
1137 ;;; This compares two bignums returning -1, 0, or 1, depending on
1138 ;;; whether a is less than, equal to, or greater than b.
1139 (declaim (ftype (function (bignum bignum) (integer -1 1)) bignum-compare))
1140 (defun bignum-compare (a b)
1141 (declare (type bignum-type a b))
1142 (let* ((len-a (%bignum-length a))
1143 (len-b (%bignum-length b))
1144 (a-plusp (%bignum-0-or-plusp a len-a))
1145 (b-plusp (%bignum-0-or-plusp b len-b)))
1146 (declare (type bignum-index len-a len-b))
1147 (cond ((not (eq a-plusp b-plusp))
1150 (do ((i (1- len-a) (1- i)))
1152 (declare (type bignum-index i))
1153 (let ((a-digit (%bignum-ref a i))
1154 (b-digit (%bignum-ref b i)))
1155 (declare (type bignum-element-type a-digit b-digit))
1156 (when (%digit-greater a-digit b-digit)
1158 (when (%digit-greater b-digit a-digit)
1160 (when (zerop i) (return 0))))
1163 (t (if a-plusp -1 1)))))
1165 ;;;; float conversion
1167 ;;; Make a single or double float with the specified significand,
1168 ;;; exponent and sign.
1169 (defun single-float-from-bits (bits exp plusp)
1170 (declare (fixnum exp))
1171 (declare (optimize #-sb-xc-host (sb!ext:inhibit-warnings 3)))
1173 sb!vm:single-float-exponent-byte
1174 (logandc2 (logand #xffffffff
1175 (%bignum-ref bits 1))
1176 sb!vm:single-float-hidden-bit))))
1180 (logior res (ash -1 sb!vm:float-sign-shift))))))
1181 (defun double-float-from-bits (bits exp plusp)
1182 (declare (fixnum exp))
1183 (declare (optimize #-sb-xc-host (sb!ext:inhibit-warnings 3)))
1185 sb!vm:double-float-exponent-byte
1186 (logandc2 (ecase sb!vm::n-word-bits
1187 (32 (%bignum-ref bits 2))
1188 (64 (ash (%bignum-ref bits 1) -32)))
1189 sb!vm:double-float-hidden-bit)))
1190 (lo (logand #xffffffff (%bignum-ref bits 1))))
1191 (make-double-float (if plusp
1193 (logior hi (ash -1 sb!vm:float-sign-shift)))
1195 #!+(and long-float x86)
1196 (defun long-float-from-bits (bits exp plusp)
1197 (declare (fixnum exp))
1198 (declare (optimize #-sb-xc-host (sb!ext:inhibit-warnings 3)))
1202 (logior exp (ash 1 15)))
1203 (%bignum-ref bits 2)
1204 (%bignum-ref bits 1)))
1206 ;;; Convert Bignum to a float in the specified Format, rounding to the best
1208 (defun bignum-to-float (bignum format)
1209 (let* ((plusp (bignum-plus-p bignum))
1210 (x (if plusp bignum (negate-bignum bignum)))
1211 (len (bignum-integer-length x))
1212 (digits (float-format-digits format))
1213 (keep (+ digits digit-size))
1214 (shift (- keep len))
1215 (shifted (if (minusp shift)
1216 (bignum-ashift-right x (- shift))
1217 (bignum-ashift-left x shift)))
1218 (low (%bignum-ref shifted 0))
1219 (round-bit (ash 1 (1- digit-size))))
1220 (declare (type bignum-index len digits keep) (fixnum shift))
1221 (labels ((round-up ()
1222 (let ((rounded (add-bignums shifted round-bit)))
1223 (if (> (integer-length rounded) keep)
1224 (float-from-bits (bignum-ashift-right rounded 1)
1226 (float-from-bits rounded len))))
1227 (float-from-bits (bits len)
1228 (declare (type bignum-index len))
1231 (single-float-from-bits
1233 (check-exponent len sb!vm:single-float-bias
1234 sb!vm:single-float-normal-exponent-max)
1237 (double-float-from-bits
1239 (check-exponent len sb!vm:double-float-bias
1240 sb!vm:double-float-normal-exponent-max)
1244 (long-float-from-bits
1246 (check-exponent len sb!vm:long-float-bias
1247 sb!vm:long-float-normal-exponent-max)
1249 (check-exponent (exp bias max)
1250 (declare (type bignum-index len))
1251 (let ((exp (+ exp bias)))
1253 ;; Why a SIMPLE-TYPE-ERROR? Well, this is mainly
1254 ;; called by COERCE, which requires an error of
1255 ;; TYPE-ERROR if the conversion can't happen
1256 ;; (except in certain circumstances when we are
1257 ;; coercing to a FUNCTION) -- CSR, 2002-09-18
1258 (error 'simple-type-error
1259 :format-control "Too large to be represented as a ~S:~% ~S"
1260 :format-arguments (list format x)
1261 :expected-type format
1266 ;; Round down if round bit is 0.
1267 ((not (logtest round-bit low))
1268 (float-from-bits shifted len))
1269 ;; If only round bit is set, then round to even.
1270 ((and (= low round-bit)
1271 (dotimes (i (- (%bignum-length x) (ceiling keep digit-size))
1273 (unless (zerop (%bignum-ref x i)) (return nil))))
1274 (let ((next (%bignum-ref shifted 1)))
1277 (float-from-bits shifted len))))
1278 ;; Otherwise, round up.
1282 ;;;; integer length and logbitp/logcount
1284 (defun bignum-buffer-integer-length (bignum len)
1285 (declare (type bignum-type bignum))
1286 (let* ((len-1 (1- len))
1287 (digit (%bignum-ref bignum len-1)))
1288 (declare (type bignum-index len len-1)
1289 (type bignum-element-type digit))
1290 (+ (integer-length (%fixnum-digit-with-correct-sign digit))
1291 (* len-1 digit-size))))
1293 (defun bignum-integer-length (bignum)
1294 (declare (type bignum-type bignum))
1295 (bignum-buffer-integer-length bignum (%bignum-length bignum)))
1297 (defun bignum-logbitp (index bignum)
1298 (declare (type bignum-type bignum))
1299 (let ((len (%bignum-length bignum)))
1300 (declare (type bignum-index len))
1301 (multiple-value-bind (word-index bit-index)
1302 (floor index digit-size)
1303 (if (>= word-index len)
1304 (not (bignum-plus-p bignum))
1305 (logbitp bit-index (%bignum-ref bignum word-index))))))
1307 (defun bignum-logcount (bignum)
1308 (declare (type bignum-type bignum))
1309 (let ((length (%bignum-length bignum))
1311 (declare (type bignum-index length)
1313 (do ((index 0 (1+ index)))
1315 (if (%bignum-0-or-plusp bignum length)
1317 (- (* length digit-size) result)))
1318 (let ((digit (%bignum-ref bignum index)))
1319 (declare (type bignum-element-type digit))
1320 (incf result (logcount digit))))))
1322 ;;;; logical operations
1326 (defun bignum-logical-not (a)
1327 (declare (type bignum-type a))
1328 (let* ((len (%bignum-length a))
1329 (res (%allocate-bignum len)))
1330 (declare (type bignum-index len))
1331 (dotimes (i len res)
1332 (declare (type bignum-index i))
1333 (setf (%bignum-ref res i) (%lognot (%bignum-ref a i))))))
1337 (defun bignum-logical-and (a b)
1338 (declare (type bignum-type a b))
1339 (let* ((len-a (%bignum-length a))
1340 (len-b (%bignum-length b))
1341 (a-plusp (%bignum-0-or-plusp a len-a))
1342 (b-plusp (%bignum-0-or-plusp b len-b)))
1343 (declare (type bignum-index len-a len-b))
1347 (logand-shorter-positive a len-a b (%allocate-bignum len-a))
1348 (logand-shorter-negative a len-a b len-b (%allocate-bignum len-b))))
1351 (logand-shorter-positive b len-b a (%allocate-bignum len-b))
1352 (logand-shorter-negative b len-b a len-a (%allocate-bignum len-a))))
1353 (t (logand-shorter-positive a len-a b (%allocate-bignum len-a))))))
1355 ;;; This takes a shorter bignum, a and len-a, that is positive. Because this
1356 ;;; is AND, we don't care about any bits longer than a's since its infinite 0
1357 ;;; sign bits will mask the other bits out of b. The result is len-a big.
1358 (defun logand-shorter-positive (a len-a b res)
1359 (declare (type bignum-type a b res)
1360 (type bignum-index len-a))
1362 (declare (type bignum-index i))
1363 (setf (%bignum-ref res i)
1364 (%logand (%bignum-ref a i) (%bignum-ref b i))))
1365 (%normalize-bignum res len-a))
1367 ;;; This takes a shorter bignum, a and len-a, that is negative. Because this
1368 ;;; is AND, we just copy any bits longer than a's since its infinite 1 sign
1369 ;;; bits will include any bits from b. The result is len-b big.
1370 (defun logand-shorter-negative (a len-a b len-b res)
1371 (declare (type bignum-type a b res)
1372 (type bignum-index len-a len-b))
1374 (declare (type bignum-index i))
1375 (setf (%bignum-ref res i)
1376 (%logand (%bignum-ref a i) (%bignum-ref b i))))
1377 (do ((i len-a (1+ i)))
1379 (declare (type bignum-index i))
1380 (setf (%bignum-ref res i) (%bignum-ref b i)))
1381 (%normalize-bignum res len-b))
1385 (defun bignum-logical-ior (a b)
1386 (declare (type bignum-type a b))
1387 (let* ((len-a (%bignum-length a))
1388 (len-b (%bignum-length b))
1389 (a-plusp (%bignum-0-or-plusp a len-a))
1390 (b-plusp (%bignum-0-or-plusp b len-b)))
1391 (declare (type bignum-index len-a len-b))
1395 (logior-shorter-positive a len-a b len-b (%allocate-bignum len-b))
1396 (logior-shorter-negative a len-a b len-b (%allocate-bignum len-b))))
1399 (logior-shorter-positive b len-b a len-a (%allocate-bignum len-a))
1400 (logior-shorter-negative b len-b a len-a (%allocate-bignum len-a))))
1401 (t (logior-shorter-positive a len-a b len-b (%allocate-bignum len-a))))))
1403 ;;; This takes a shorter bignum, a and len-a, that is positive. Because this
1404 ;;; is IOR, we don't care about any bits longer than a's since its infinite
1405 ;;; 0 sign bits will mask the other bits out of b out to len-b. The result
1407 (defun logior-shorter-positive (a len-a b len-b res)
1408 (declare (type bignum-type a b res)
1409 (type bignum-index len-a len-b))
1411 (declare (type bignum-index i))
1412 (setf (%bignum-ref res i)
1413 (%logior (%bignum-ref a i) (%bignum-ref b i))))
1414 (do ((i len-a (1+ i)))
1416 (declare (type bignum-index i))
1417 (setf (%bignum-ref res i) (%bignum-ref b i)))
1418 (%normalize-bignum res len-b))
1420 ;;; This takes a shorter bignum, a and len-a, that is negative. Because this
1421 ;;; is IOR, we just copy any bits longer than a's since its infinite 1 sign
1422 ;;; bits will include any bits from b. The result is len-b long.
1423 (defun logior-shorter-negative (a len-a b len-b res)
1424 (declare (type bignum-type a b res)
1425 (type bignum-index len-a len-b))
1427 (declare (type bignum-index i))
1428 (setf (%bignum-ref res i)
1429 (%logior (%bignum-ref a i) (%bignum-ref b i))))
1430 (do ((i len-a (1+ i))
1431 (sign (%sign-digit a len-a)))
1433 (declare (type bignum-index i))
1434 (setf (%bignum-ref res i) sign))
1435 (%normalize-bignum res len-b))
1439 (defun bignum-logical-xor (a b)
1440 (declare (type bignum-type a b))
1441 (let ((len-a (%bignum-length a))
1442 (len-b (%bignum-length b)))
1443 (declare (type bignum-index len-a len-b))
1445 (bignum-logical-xor-aux a len-a b len-b (%allocate-bignum len-b))
1446 (bignum-logical-xor-aux b len-b a len-a (%allocate-bignum len-a)))))
1448 ;;; This takes the shorter of two bignums in a and len-a. Res is len-b
1449 ;;; long. Do the XOR.
1450 (defun bignum-logical-xor-aux (a len-a b len-b res)
1451 (declare (type bignum-type a b res)
1452 (type bignum-index len-a len-b))
1454 (declare (type bignum-index i))
1455 (setf (%bignum-ref res i)
1456 (%logxor (%bignum-ref a i) (%bignum-ref b i))))
1457 (do ((i len-a (1+ i))
1458 (sign (%sign-digit a len-a)))
1460 (declare (type bignum-index i))
1461 (setf (%bignum-ref res i) (%logxor sign (%bignum-ref b i))))
1462 (%normalize-bignum res len-b))
1464 ;;;; There used to be a bunch of code to implement "efficient" versions of LDB
1465 ;;;; and DPB here. But it apparently was never used, so it's been deleted.
1466 ;;;; --njf, 2007-02-04
1470 ;;; This is the original sketch of the algorithm from which I implemented this
1471 ;;; TRUNCATE, assuming both operands are bignums. I should modify this to work
1472 ;;; with the documentation on my functions, as a general introduction. I've
1473 ;;; left this here just in case someone needs it in the future. Don't look at
1474 ;;; this unless reading the functions' comments leaves you at a loss. Remember
1475 ;;; this comes from Knuth, so the book might give you the right general
1480 ;;; If X's magnitude is less than Y's, then result is 0 with remainder X.
1482 ;;; Make x and y positive, copying x if it is already positive.
1484 ;;; Shift y left until there's a 1 in the 30'th bit (most significant, non-sign
1486 ;;; Just do most sig digit to determine how much to shift whole number.
1487 ;;; Shift x this much too.
1488 ;;; Remember this initial shift count.
1490 ;;; Allocate q to be len-x minus len-y quantity plus 1.
1492 ;;; i = last digit of x.
1493 ;;; k = last digit of q.
1497 ;;; j = last digit of y.
1500 ;;; if x[i] = y[j] then g = (1- (ash 1 digit-size))
1501 ;;; else g = x[i]x[i-1]/y[j].
1504 ;;; %UNSIGNED-MULTIPLY returns b and c defined below.
1505 ;;; a = x[i-1] - (logand (* g y[j]) #xFFFFFFFF).
1506 ;;; Use %UNSIGNED-MULTIPLY taking low-order result.
1507 ;;; b = (logand (ash (* g y[j-1]) (- digit-size)) (1- (ash 1 digit-size))).
1508 ;;; c = (logand (* g y[j-1]) (1- (ash 1 digit-size))).
1510 ;;; if a > b, guess is too high
1511 ;;; g = g - 1; go back to "check guess".
1512 ;;; if a = b and c > x[i-2], guess is too high
1513 ;;; g = g - 1; go back to "check guess".
1514 ;;; GUESS IS 32-BIT NUMBER, SO USE THING TO KEEP IN SPECIAL REGISTER
1515 ;;; SAME FOR A, B, AND C.
1517 ;;; Subtract g * y from x[i - len-y+1]..x[i]. See paper for doing this in step.
1518 ;;; If x[i] < 0, guess is screwed up.
1519 ;;; negative g, then add 1
1520 ;;; zero or positive g, then subtract 1
1521 ;;; AND add y back into x[len-y+1..i].
1527 ;;; If k>=0, goto LOOP.
1529 ;;; Now quotient is good, but remainder is not.
1530 ;;; Shift x right by saved initial left shifting count.
1532 ;;; Check quotient and remainder signs.
1533 ;;; x pos y pos --> q pos r pos
1534 ;;; x pos y neg --> q neg r pos
1535 ;;; x neg y pos --> q neg r neg
1536 ;;; x neg y neg --> q pos r neg
1538 ;;; Normalize quotient and remainder. Cons result if necessary.
1541 ;;; This used to be split into multiple functions, which shared state
1542 ;;; in special variables *TRUNCATE-X* and *TRUNCATE-Y*. Having so many
1543 ;;; special variable accesses in tight inner loops was having a large
1544 ;;; effect on performance, so the helper functions have now been
1545 ;;; refactored into local functions and the special variables into
1546 ;;; lexicals. There was also a lot of boxing and unboxing of
1547 ;;; (UNSIGNED-BYTE 32)'s going on, which this refactoring
1548 ;;; eliminated. This improves the performance on some CL-BENCH tests
1549 ;;; by up to 50%, which is probably signigicant enough to justify the
1550 ;;; reduction in readability that was introduced. --JES, 2004-08-07
1551 (defun bignum-truncate (x y)
1552 (declare (type bignum-type x y))
1553 (let (truncate-x truncate-y)
1555 ;;; Divide X by Y when Y is a single bignum digit. BIGNUM-TRUNCATE
1556 ;;; fixes up the quotient and remainder with respect to sign and
1559 ;;; We don't have to worry about shifting Y to make its most
1560 ;;; significant digit sufficiently large for %FLOOR to return
1561 ;;; digit-size quantities for the q-digit and r-digit. If Y is
1562 ;;; a single digit bignum, it is already large enough for
1563 ;;; %FLOOR. That is, it has some bits on pretty high in the
1565 ((bignum-truncate-single-digit (x len-x y)
1566 (declare (type bignum-index len-x))
1567 (let ((y (%bignum-ref y 0)))
1568 (declare (type bignum-element-type y))
1569 (if (not (logtest y (1- y)))
1570 ;; Y is a power of two.
1571 ;; SHIFT-RIGHT-UNALIGNED won't do the right thing
1572 ;; with a shift count of 0 or -1, so special case this.
1574 (error 'division-by-zero))
1576 ;; We could probably get away with (VALUES X 0)
1577 ;; here, but it's not clear that some of the
1578 ;; normalization logic further down would avoid
1579 ;; mutilating X. Just go ahead and cons, consing's
1581 (values (copy-bignum x len-x) 0))
1583 (let ((n-bits (1- (integer-length y))))
1585 (shift-right-unaligned x 0 n-bits len-x
1587 (setf (%bignum-ref res j)
1588 (%ashr (%bignum-ref x i) n-bits))
1591 (logand (%bignum-ref x 0) (1- y))))))
1592 (do ((i (1- len-x) (1- i))
1593 (q (%allocate-bignum len-x))
1596 (let ((rem (%allocate-bignum 1)))
1597 (setf (%bignum-ref rem 0) r)
1599 (declare (type bignum-element-type r))
1600 (multiple-value-bind (q-digit r-digit)
1601 (%floor r (%bignum-ref x i) y)
1602 (declare (type bignum-element-type q-digit r-digit))
1603 (setf (%bignum-ref q i) q-digit)
1604 (setf r r-digit))))))
1605 ;;; This returns a guess for the next division step. Y1 is the
1606 ;;; highest y digit, and y2 is the second to highest y
1607 ;;; digit. The x... variables are the three highest x digits
1608 ;;; for the next division step.
1610 ;;; From Knuth, our guess is either all ones or x-i and x-i-1
1611 ;;; divided by y1, depending on whether x-i and y1 are the
1612 ;;; same. We test this guess by determining whether guess*y2
1613 ;;; is greater than the three high digits of x minus guess*y1
1614 ;;; shifted left one digit:
1615 ;;; ------------------------------
1616 ;;; | x-i | x-i-1 | x-i-2 |
1617 ;;; ------------------------------
1618 ;;; ------------------------------
1619 ;;; - | g*y1 high | g*y1 low | 0 |
1620 ;;; ------------------------------
1621 ;;; ... < guess*y2 ???
1622 ;;; If guess*y2 is greater, then we decrement our guess by one
1623 ;;; and try again. This returns a guess that is either
1624 ;;; correct or one too large.
1625 (bignum-truncate-guess (y1 y2 x-i x-i-1 x-i-2)
1626 (declare (type bignum-element-type y1 y2 x-i x-i-1 x-i-2))
1627 (let ((guess (if (%digit-compare x-i y1)
1629 (%floor x-i x-i-1 y1))))
1630 (declare (type bignum-element-type guess))
1632 (multiple-value-bind (high-guess*y1 low-guess*y1)
1633 (%multiply guess y1)
1634 (declare (type bignum-element-type low-guess*y1
1636 (multiple-value-bind (high-guess*y2 low-guess*y2)
1637 (%multiply guess y2)
1638 (declare (type bignum-element-type high-guess*y2
1640 (multiple-value-bind (middle-digit borrow)
1641 (%subtract-with-borrow x-i-1 low-guess*y1 1)
1642 (declare (type bignum-element-type middle-digit)
1644 ;; Supplying borrow of 1 means there was no
1645 ;; borrow, and we know x-i-2 minus 0 requires
1647 (let ((high-digit (%subtract-with-borrow x-i
1650 (declare (type bignum-element-type high-digit))
1651 (if (and (%digit-compare high-digit 0)
1652 (or (%digit-greater high-guess*y2
1654 (and (%digit-compare middle-digit
1656 (%digit-greater low-guess*y2
1658 (setf guess (%subtract-with-borrow guess 1 1))
1659 (return guess)))))))))
1660 ;;; Divide TRUNCATE-X by TRUNCATE-Y, returning the quotient
1661 ;;; and destructively modifying TRUNCATE-X so that it holds
1664 ;;; LEN-X and LEN-Y tell us how much of the buffers we care about.
1666 ;;; TRUNCATE-X definitely has at least three digits, and it has one
1667 ;;; more than TRUNCATE-Y. This keeps i, i-1, i-2, and low-x-digit
1668 ;;; happy. Thanks to SHIFT-AND-STORE-TRUNCATE-BUFFERS.
1669 (return-quotient-leaving-remainder (len-x len-y)
1670 (declare (type bignum-index len-x len-y))
1671 (let* ((len-q (- len-x len-y))
1672 ;; Add one for extra sign digit in case high bit is on.
1673 (q (%allocate-bignum (1+ len-q)))
1675 (y1 (%bignum-ref truncate-y (1- len-y)))
1676 (y2 (%bignum-ref truncate-y (- len-y 2)))
1680 (low-x-digit (- i len-y)))
1681 (declare (type bignum-index len-q k i i-1 i-2 low-x-digit)
1682 (type bignum-element-type y1 y2))
1684 (setf (%bignum-ref q k)
1685 (try-bignum-truncate-guess
1686 ;; This modifies TRUNCATE-X. Must access
1687 ;; elements each pass.
1688 (bignum-truncate-guess y1 y2
1689 (%bignum-ref truncate-x i)
1690 (%bignum-ref truncate-x i-1)
1691 (%bignum-ref truncate-x i-2))
1693 (cond ((zerop k) (return))
1696 (shiftf i i-1 i-2 (1- i-2)))))
1698 ;;; This takes a digit guess, multiplies it by TRUNCATE-Y for a
1699 ;;; result one greater in length than LEN-Y, and subtracts this result
1700 ;;; from TRUNCATE-X. LOW-X-DIGIT is the first digit of X to start
1701 ;;; the subtraction, and we know X is long enough to subtract a LEN-Y
1702 ;;; plus one length bignum from it. Next we check the result of the
1703 ;;; subtraction, and if the high digit in X became negative, then our
1704 ;;; guess was one too big. In this case, return one less than GUESS
1705 ;;; passed in, and add one value of Y back into X to account for
1706 ;;; subtracting one too many. Knuth shows that the guess is wrong on
1707 ;;; the order of 3/b, where b is the base (2 to the digit-size power)
1708 ;;; -- pretty rarely.
1709 (try-bignum-truncate-guess (guess len-y low-x-digit)
1710 (declare (type bignum-index low-x-digit len-y)
1711 (type bignum-element-type guess))
1712 (let ((carry-digit 0)
1715 (declare (type bignum-element-type carry-digit)
1716 (type bignum-index i)
1718 ;; Multiply guess and divisor, subtracting from dividend
1721 (multiple-value-bind (high-digit low-digit)
1722 (%multiply-and-add guess
1723 (%bignum-ref truncate-y j)
1725 (declare (type bignum-element-type high-digit low-digit))
1726 (setf carry-digit high-digit)
1727 (multiple-value-bind (x temp-borrow)
1728 (%subtract-with-borrow (%bignum-ref truncate-x i)
1731 (declare (type bignum-element-type x)
1732 (fixnum temp-borrow))
1733 (setf (%bignum-ref truncate-x i) x)
1734 (setf borrow temp-borrow)))
1736 (setf (%bignum-ref truncate-x i)
1737 (%subtract-with-borrow (%bignum-ref truncate-x i)
1738 carry-digit borrow))
1739 ;; See whether guess is off by one, adding one
1740 ;; Y back in if necessary.
1741 (cond ((%digit-0-or-plusp (%bignum-ref truncate-x i))
1744 ;; If subtraction has negative result, add one
1745 ;; divisor value back in. The guess was one too
1746 ;; large in magnitude.
1747 (let ((i low-x-digit)
1750 (multiple-value-bind (v k)
1751 (%add-with-carry (%bignum-ref truncate-y j)
1752 (%bignum-ref truncate-x i)
1754 (declare (type bignum-element-type v))
1755 (setf (%bignum-ref truncate-x i) v)
1758 (setf (%bignum-ref truncate-x i)
1759 (%add-with-carry (%bignum-ref truncate-x i)
1761 (%subtract-with-borrow guess 1 1)))))
1762 ;;; This returns the amount to shift y to place a one in the
1763 ;;; second highest bit. Y must be positive. If the last digit
1764 ;;; of y is zero, then y has a one in the previous digit's
1765 ;;; sign bit, so we know it will take one less than digit-size
1766 ;;; to get a one where we want. Otherwise, we count how many
1767 ;;; right shifts it takes to get zero; subtracting this value
1768 ;;; from digit-size tells us how many high zeros there are
1769 ;;; which is one more than the shift amount sought.
1771 ;;; Note: This is exactly the same as one less than the
1772 ;;; integer-length of the last digit subtracted from the
1775 ;;; We shift y to make it sufficiently large that doing the
1776 ;;; 2*digit-size by digit-size %FLOOR calls ensures the quotient and
1777 ;;; remainder fit in digit-size.
1778 (shift-y-for-truncate (y)
1779 (let* ((len (%bignum-length y))
1780 (last (%bignum-ref y (1- len))))
1781 (declare (type bignum-index len)
1782 (type bignum-element-type last))
1783 (- digit-size (integer-length last) 1)))
1784 ;;; Stores two bignums into the truncation bignum buffers,
1785 ;;; shifting them on the way in. This assumes x and y are
1786 ;;; positive and at least two in length, and it assumes
1787 ;;; truncate-x and truncate-y are one digit longer than x and
1789 (shift-and-store-truncate-buffers (x len-x y len-y shift)
1790 (declare (type bignum-index len-x len-y)
1791 (type (integer 0 (#.digit-size)) shift))
1792 (cond ((zerop shift)
1793 (bignum-replace truncate-x x :end1 len-x)
1794 (bignum-replace truncate-y y :end1 len-y))
1796 (bignum-ashift-left-unaligned x 0 shift (1+ len-x)
1798 (bignum-ashift-left-unaligned y 0 shift (1+ len-y)
1799 truncate-y))))) ;; LABELS
1800 ;;; Divide X by Y returning the quotient and remainder. In the
1801 ;;; general case, we shift Y to set up for the algorithm, and we
1802 ;;; use two buffers to save consing intermediate values. X gets
1803 ;;; destructively modified to become the remainder, and we have
1804 ;;; to shift it to account for the initial Y shift. After we
1805 ;;; multiple bind q and r, we first fix up the signs and then
1806 ;;; return the normalized results.
1807 (let* ((x-plusp (%bignum-0-or-plusp x (%bignum-length x)))
1808 (y-plusp (%bignum-0-or-plusp y (%bignum-length y)))
1809 (x (if x-plusp x (negate-bignum x nil)))
1810 (y (if y-plusp y (negate-bignum y nil)))
1811 (len-x (%bignum-length x))
1812 (len-y (%bignum-length y)))
1813 (multiple-value-bind (q r)
1815 (bignum-truncate-single-digit x len-x y))
1816 ((plusp (bignum-compare y x))
1817 (let ((res (%allocate-bignum len-x)))
1819 (setf (%bignum-ref res i) (%bignum-ref x i)))
1822 (let ((len-x+1 (1+ len-x)))
1823 (setf truncate-x (%allocate-bignum len-x+1))
1824 (setf truncate-y (%allocate-bignum (1+ len-y)))
1825 (let ((y-shift (shift-y-for-truncate y)))
1826 (shift-and-store-truncate-buffers x len-x y
1828 (values (return-quotient-leaving-remainder len-x+1
1830 ;; Now that RETURN-QUOTIENT-LEAVING-REMAINDER
1831 ;; has executed, we just tidy up the remainder
1832 ;; (in TRUNCATE-X) and return it.
1835 (let ((res (%allocate-bignum len-y)))
1836 (declare (type bignum-type res))
1837 (bignum-replace res truncate-x :end2 len-y)
1838 (%normalize-bignum res len-y)))
1840 (shift-right-unaligned
1841 truncate-x 0 y-shift len-y
1843 (setf (%bignum-ref res j)
1844 (%ashr (%bignum-ref truncate-x i)
1846 (%normalize-bignum res res-len))
1848 (let ((quotient (cond ((eq x-plusp y-plusp) q)
1849 ((typep q 'fixnum) (the fixnum (- q)))
1850 (t (negate-bignum-in-place q))))
1851 (rem (cond (x-plusp r)
1852 ((typep r 'fixnum) (the fixnum (- r)))
1853 (t (negate-bignum-in-place r)))))
1854 (values (if (typep quotient 'fixnum)
1856 (%normalize-bignum quotient (%bignum-length quotient)))
1857 (if (typep rem 'fixnum)
1859 (%normalize-bignum rem (%bignum-length rem))))))))))
1862 ;;;; There used to be a pile of code for implementing division for bignum digits
1863 ;;;; for machines that don't have a 2*digit-size by digit-size divide instruction.
1864 ;;;; This happens to be most machines, but all the SBCL ports seem to be content
1865 ;;;; to implement SB-BIGNUM:%FLOOR as a VOP rather than using the code here.
1866 ;;;; So it's been deleted. --njf, 2007-02-04
1868 ;;;; general utilities
1870 ;;; Internal in-place operations use this to fixup remaining digits in the
1871 ;;; incoming data, such as in-place shifting. This is basically the same as
1872 ;;; the first form in %NORMALIZE-BIGNUM, but we return the length of the buffer
1873 ;;; instead of shrinking the bignum.
1874 #!-sb-fluid (declaim (sb!ext:maybe-inline %normalize-bignum-buffer))
1875 (defun %normalize-bignum-buffer (result len)
1876 (declare (type bignum-type result)
1877 (type bignum-index len))
1879 (do ((next-digit (%bignum-ref result (- len 2))
1880 (%bignum-ref result (- len 2)))
1881 (sign-digit (%bignum-ref result (1- len)) next-digit))
1882 ((not (zerop (logxor sign-digit (%ashr next-digit (1- digit-size))))))
1884 (setf (%bignum-ref result len) 0)
1889 ;;; This drops the last digit if it is unnecessary sign information. It repeats
1890 ;;; this as needed, possibly ending with a fixnum. If the resulting length from
1891 ;;; shrinking is one, see whether our one word is a fixnum. Shift the possible
1892 ;;; fixnum bits completely out of the word, and compare this with shifting the
1893 ;;; sign bit all the way through. If the bits are all 1's or 0's in both words,
1894 ;;; then there are just sign bits between the fixnum bits and the sign bit. If
1895 ;;; we do have a fixnum, shift it over for the two low-tag bits.
1896 (defun %normalize-bignum (result len)
1897 (declare (type bignum-type result)
1898 (type bignum-index len)
1899 (inline %normalize-bignum-buffer))
1900 (let ((newlen (%normalize-bignum-buffer result len)))
1901 (declare (type bignum-index newlen))
1902 (unless (= newlen len)
1903 (%bignum-set-length result newlen))
1905 (let ((digit (%bignum-ref result 0)))
1906 (if (= (%ashr digit sb!vm:n-positive-fixnum-bits)
1907 (%ashr digit (1- digit-size)))
1908 (%fixnum-digit-with-correct-sign digit)
1912 ;;; This drops the last digit if it is unnecessary sign information. It
1913 ;;; repeats this as needed, possibly ending with a fixnum magnitude but never
1914 ;;; returning a fixnum.
1915 (defun %mostly-normalize-bignum (result len)
1916 (declare (type bignum-type result)
1917 (type bignum-index len)
1918 (inline %normalize-bignum-buffer))
1919 (let ((newlen (%normalize-bignum-buffer result len)))
1920 (declare (type bignum-index newlen))
1921 (unless (= newlen len)
1922 (%bignum-set-length result newlen))
1927 ;;; the bignum case of the SXHASH function
1928 (defun sxhash-bignum (x)
1929 (let ((result 316495330))
1930 (declare (type fixnum result))
1931 (dotimes (i (%bignum-length x))
1932 (declare (type index i))
1933 (let ((xi (%bignum-ref x i)))
1935 (logand most-positive-fixnum