[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