[gambit-list] Big number Bug?

Bradley Lucier lucier at math.purdue.edu
Thu Apr 26 12:28:45 EDT 2007


On Apr 26, 2007, at 11:47 AM, Bradley Lucier wrote:

> Here's a fix for the bug.  (Marc, can you change this in _num.scm?)

Here's a somewhat better fix (faster for some "obvious" cases, which  
I hope are correct ;-).

(define-prim (##exact-int.div x y)

   (define (big-quotient x y)
     (let* ((x-negative? (##negative? x))
	   (abs-x (if x-negative? (##negate x) x))
	   (y-negative? (##negative? y))
	   (abs-y (if y-negative? (##negate y) y)))
       (if (##< abs-x abs-y)
	  (##cons 0 x)
	
	  ;; at least one of x and y is a bignum, so
	  ;; here abs-x must be a bignum
	
	  (let ((result (##bignum.div abs-x abs-y)))
	
	    (if (##not (##eq? x-negative? y-negative?))
		(##set-car! result (##negate (##car result))))
	
	    (if x-negative?
		(##set-cdr! result (##negate (##cdr result))))
	
	    result))))

   (cond ((##eq? y 1)
          (##cons x 0))
         ((##eq? y -1)
          (##cons (##negate x) 0))
         ((##eq? x y)              ;; can come up in rational arithmetic
          (##cons 1 0))
         ((##fixnum? x)
	 (if (##fixnum? y)
	     (##cons (##fixnum.quotient x y) ; note: y can't be -1
		     (##fixnum.remainder x y))
	     ;; y is a bignum, x is a fixnum
	     (if (##fixnum.< 1 (##bignum.adigit-length y))
		 ;; y has at least two adigits, so
		 ;; (abs y) > (abs x)
		 (##cons 0 x)
		 (big-quotient x y))))
	((and (##bignum? y)
	      (##fixnum.< 1 (##fixnum.- (##bignum.adigit-length y)
					(##bignum.adigit-length x))))
	 ;; x and y are bignums, and y has at least two more adigits
	 ;; than x, so (abs y) > (abs x)
	 (##cons 0 x))
	(else
          (big-quotient x y))))



More information about the Gambit-list mailing list