[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

*To*: William D Clinger <will@xxxxxxxxxxx>*Subject*: Re: div0 and mod0*From*: Bradley Lucier <lucier@xxxxxxxxxxxxxxx>*Date*: Sun, 27 Aug 2006 19:16:03 -0400*Cc*: Bradley Lucier <lucier@xxxxxxxxxxxxxxx>, srfi-77@xxxxxxxxxxxxxxxxx*Delivered-to*: srfi-77@xxxxxxxxxxxxxxxxx*In-reply-to*: <E1GCjOI-00034r-WC@xxxxxxxxxxxxxxxxx>*References*: <E1GCjOI-00034r-WC@xxxxxxxxxxxxxxxxx>

On Aug 14, 2006, at 4:50 PM, William D Clinger wrote:

The current revision of the reference implementation for SRFI 77 contains the following uses of div0 and mod0. (I have edited this to remove some debugging code that would be removed in the next major version anyway.) Similar uses of div0 and mod0 are found in the definition of fixnum*/carry, and similar uses will be found in a more efficient version of the bignum code if I ever get around to writing it. ; The challenge of fixnum*/2 is to avoid overflow when ; computing the intermediate results. That is done here ; by computing modulo 1/2 the usual modulus, which this ; code assumes to be an even power of two. ; ; (a * m + b) * (c * m + d) ; = (a * c) * m^2 + (a * d + b * c) * m + b * d (define (fixnum*/2 x y) (call-with-values (lambda () (fixnum-div0+mod0 x *half-modulus*)) (lambda (a b) (call-with-values (lambda () (fixnum-div0+mod0 y *half-modulus*)) (lambda (c d) (let* ((a*d (r5rs:* a d)) (b*c (r5rs:* b c)) (b*d (r5rs:* b d)) (a*d+b*c (fixnum+/2 a*d b*c)) (hibits (fixnum-mod a*d+b*c *half-modulus*)) (hibits (if (fixnum>? hibits *half-high*) (fixnum- hibits *half-modulus*) hibits)) (hi (r5rs:* hibits *half-modulus*)) (lo b*d)) (fixnum+/2 hi lo)))))))

Will:

(##fixnum.+ x y) (adds with wrapping on overflow) (##fixnum.+? x y) (returns x+y if it's a fixnum, or #f otherwise) (##fixnum.* x y) (returns wrapped version of x*y)

(##fixnum.- x y) (returns wrapped version of x-y) (##fixnum.-? x y) (returns x-y if it's a fixnum, or #f otherwise)

##fixnum.quotient ##fixnum.remainder ##fixnum.modulo

(##fixnum.*? x y) calculates (temp = x*y, (temp/y=x ? temp : #f))

(cond ((##fixnum.= y 0) 0) ((if (##fixnum.= y -1) (##fixnum.-? x) (##fixnum.*? x y)) => (lambda (result) result)) (else (##bignum.* (##bignum.<-fixnum x) (##bignum.<-fixnum y))))

But I don't intend to do that. Brad

**References**:**Re: div0 and mod0***From:*William D Clinger

- Prev by Date:
**Re: div0 and mod0** - Next by Date:
**Re: div0 and mod0** - Previous by thread:
**Re: div0 and mod0** - Next by thread:
**Re: div0 and mod0** - Index(es):