-;;;; some stuff to check that bignum operations are returning correct
-;;;; results
-
-;;;; This software is part of the SBCL system. See the README file for
-;;;; more information.
-;;;;
-;;;; This software is derived from the CMU CL system, which was
-;;;; written at Carnegie Mellon University and released into the
-;;;; public domain. The software is in the public domain and is
-;;;; provided with absolutely no warranty. See the COPYING and CREDITS
-;;;; files for more information.
-
-(in-package "SB!BIGNUM")
-
-(file-comment
- "$Header$")
-
-(defvar *in-bignum-wrapper* nil)
-
-(defmacro def-bignum-wrapper (name lambda-list &body body)
- (let ((var-name (sb!int:symbolicate "*OLD-" name "*"))
- (wrap-name (sb!int:symbolicate "WRAP-" name))
- (args (mapcar #'(lambda (x)
- (if (listp x) (car x) x))
- (remove-if #'(lambda (x)
- (member x lambda-list-keywords))
- lambda-list))))
- `(progn
- (defvar ,var-name (fdefinition ',name))
- (defun ,wrap-name ,lambda-list
- (if *in-bignum-wrapper*
- (funcall ,var-name ,@args)
- (let ((*in-bignum-wrapper* t))
- ,@body)))
- (setf (fdefinition ',name) #',wrap-name))))
-
-(defun big= (x y)
- (= (if (typep x 'bignum)
- (%normalize-bignum x (%bignum-length x))
- x)
- (if (typep y 'bignum)
- (%normalize-bignum y (%bignum-length y))
- y)))
-
-(def-bignum-wrapper add-bignums (x y)
- (let ((res (funcall *old-add-bignums* x y)))
- (assert (big= (- res y) x))
- res))
-
-(def-bignum-wrapper multiply-bignums (x y)
- (let ((res (funcall *old-multiply-bignums* x y)))
- (if (zerop x)
- (assert (zerop res))
- (multiple-value-bind (q r) (truncate res x)
- (assert (and (zerop r) (big= q y)))))
- res))
-
-(def-bignum-wrapper negate-bignum (x &optional (fully-normalized t))
- (let ((res (funcall *old-negate-bignum* x fully-normalized)))
- (assert (big= (- res) x))
- res))
-
-(def-bignum-wrapper subtract-bignum (x y)
- (let ((res (funcall *old-subtract-bignum* x y)))
- (assert (big= (+ res y) x))
- res))
-
-(def-bignum-wrapper multiply-bignum-and-fixnum (x y)
- (let ((res (funcall *old-multiply-bignum-and-fixnum* x y)))
- (if (zerop x)
- (assert (zerop res))
- (multiple-value-bind (q r) (truncate res x)
- (assert (and (zerop r) (big= q y)))))
- res))
-
-(def-bignum-wrapper multiply-fixnums (x y)
- (let ((res (funcall *old-multiply-fixnums* x y)))
- (if (zerop x)
- (assert (zerop res))
- (multiple-value-bind (q r) (truncate res x)
- (assert (and (zerop r) (big= q y)))))
- res))
-
-(def-bignum-wrapper bignum-ashift-right (x shift)
- (let ((res (funcall *old-bignum-ashift-right* x shift)))
- (assert (big= (ash res shift) (logand x (ash -1 shift))))
- res))
-
-(def-bignum-wrapper bignum-ashift-left (x shift)
- (let ((res (funcall *old-bignum-ashift-left* x shift)))
- (assert (big= (ash res (- shift)) x))
- res))
-
-(def-bignum-wrapper bignum-truncate (x y)
- (multiple-value-bind (q r) (funcall *old-bignum-truncate* x y)
- (assert (big= (+ (* q y) r) x))
- (values q r)))
-
-(def-bignum-wrapper bignum-compare (x y)
- (let ((res (funcall *old-bignum-compare* x y)))
- (assert (big= (signum (- x y)) res))
- res))