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

*To*: ALAN at MIT-MC, DLA at MIT-EECS*From*: JONL at MIT-MC (Jon L White)*Date*: Sun ,15 Mar 81 01:16:00 EDT*Cc*: (BUG LISP) at MIT-MC, INFO-LISPM at MIT-MC

Date: 14 March 1981 00:36-EST From: Alan Bawden <ALAN at MIT-MC> Date: 14 Mar 1981 0007-EST From: David L. Andre <DLA at MIT-EECS> Is it possible to get, in a single operation, both the quotient and remainder in a fixnum division? I have often wanted to do something like: (MULTIPLE-VALUE (QUO REM) (FLOOR A B)) So have I. Unfortunately it is rather difficult to get this to work since arithmetic is performed in microcode, and it is difficult to get multiple values out from microcode. . . . I can appreciate your comments about how the hardware loses -- the IBM370 produces a floating-division result much like the PDP-10 FDVL instruction, and then proceeds to round according to its own fixed rule. During my time working for there, I needed to experiment with some alternate rounding schemes, and was chagrin'd to discover that there was no way to get the "remainder" part out of the "internal" registers and into a place where the macro-code instructions could access it. foo. I've implemented some internal fixnum functions for NIL, so that generic arithemetic can be fully-implemented in LISP -- basically they represent the four rational operations as implemented by most 2's- complement computers. For a real NIL, the compiler is open-coding them "by special discernment", rather than by doing a multiple-value-returning function call; so it only is a matter of being able to get at all the bits implicit in the two results. I've coded up this stuff for the PDP10 too, but the COMPLR doesn't open-compile these funs; rather, it calls some quick, handy little LAP subrs. Below is reproduced the documentation on them from file MC:NIL;NEWFUN > SI:FULLADD (SI:FULLADD x y carry_in) ==> [sum.x+y+carry_in, carry_out] SI:FULLSUB (SI:FULLSUB x y carry_in) ==> [difference.x-y+carry_in, carry_out] Where the sum and difference indicated are two's complement results, and the "carry"s are all restricted to -1, 0 and +1. Since true integer addition cannot be restricted to a finite range, there must be "wrap-around" even in these functions. Thus, let n+1 be the number of bits in the FIXNUM (two's-complement) representation; then mx :== 2^n - 1 ;maximum representible (positive) FIXNUM mnx :== -2^n ;minimum representible (negative) FIXNUM Then both (SI:FULLADD mnx mnx -1) and (SI:FULLSUB mx mnx 1) will "wrap-around" (i.e., "overflow"). Thus a fail-safe, but slightly pessimistic, test for "overflow" is merely to test the second argument for being equal to "mnx". Happily, the most important system usages of these two have an explicit 0 carry_in, but at a few places in the BIGNUM implementation they require the full generality. SI:FULLMUL (SI:FULLMUL x y carry_in) ==> let productsum == x*y+carry_in [productsum.rem.by.2^n, productsum.div.by.2^n] Note that if both x and y are equal to "mnx" as described above, the the result will "overflow". SI:FULLDIV (SI:FULLDIV low hi divsr) ==> [quotient, remainder] The division indicated is (hi*2^n+low)/divsr

- Prev by Date:
**Logo graphics for the Lisp Machine** - Next by Date:
**FIXing functions** - Previous by thread:
**Logo graphics for the Lisp Machine** - Next by thread:
**FIXing functions** - Index(es):