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

[no subject]

    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
	  (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.
  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