Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-02 - 43,50216/bignum.mac
There are 2 other files named bignum.mac in the archive. Click here to see a list.
TITLE BIGNUM ARITHMETIC

;AC DEFINITIONS
NIL=0
A=1
B=2
C=3
T=6
TT=7
T10=10
FF=16
AR1=4
F=15
P=14
D=12
S=11
AR2A=5
R=13
SP=17

INUMIN=377777
INUM0=577777
SIGN=400000
MINSGN==10

INTERNAL BIGINI

EXTERNAL CONS,FWCONS,ACONS,NCONS,XCONS,VBASE,VNOPOINT,LAST,NUMVAL
EXTERNAL POSNUM,NEGNUM,NUM1,CTY,EVBIG,REVERSE,BPR
EXTERNAL TRUE,FALSE,NUMV2,FIXNUM,FLONUM,FIX1A,LENGTH,MINUSP
EXTERNAL BPR,NUM3,EVBIG,NUMV4,OPOV,NUMV3,NUMBP2,FIX2,OPR,FLOOV
PAGE
;POWER OF TEN
PWR10:	MOVEM B,BASEX#
	MOVE C,B
	IMUL B,B	;BASE^2
	IMUL B,B	;BASE^4
	IMUL B,C	;BASE^5
	IMUL B,B	;BASE^TEN
	MOVEM B,BASE10#
	POPJ P,

B0CONS:	MOVEI A,0
BNCONS:	MOVEI B,0
BCONS:	PUSHJ P,FWCONS
	JRST CONS

QCONS=ACONS-1
PAGE
;INITIALIZE THE BIGNUM SYSTEM BY CHANGING MAGIC LOCATIONS IN LISP
BIGINI:	MOVE A,[JRST BPRINT]
	MOVEM A,BPR		;PRINT
	HRRI A,BIGEV	
	MOVEM A,EVBIG		;EVAL
	HRRI A,NUMVB
	MOVEM A,NUMV4		;NUMVAL
	HRRI A,BIGDIS	
	MOVEM A,NUMV3		;BIGNUM OPS
	HRRI A,BIGNP
	MOVEM A,NUMBP2		;NUMBERP
	HRRI A,RDBNM
	HRRM A,NUM3		;READ
	HRRI A,FIXOVL
	HRRM A,OPOV		;OVERFLOW
	HRRI A,BFIX
	HRRM A,FIX2		;FIX
	JRST FALSE
PAGE
;BIGNUM PRINT
;BPR IN LISP IS JRST BPRINT
BPRINT:	CAIN B,POSNUM
	JRST BPRIN2
	CAIE B,NEGNUM
	JRST BPR+1
	XCT "-",CTY
BPRIN2:	PUSHJ P,COPY
	PUSHJ P,BPRI
	POPJ P,

BPRI:	MOVE B,VBASE
	SUBI B,INUM0
	PUSHJ P,PWR10
	PUSHJ P,BPRJ
	SKIPE A,VNOPOINT
	POPJ P,
	MOVE A,BASEX
	CAIE A,12
	POPJ P,
	MOVEI A,"."
	JRST (R)	;PARTICULAR TYO

BPRJ:	MOVE B,BASE10
	PUSHJ P,Q1
	JUMPE B,BPR2	;ZERO QUOTIENT
	PUSH P,A	;REMAINDER
	MOVE A,B	;QUOTIENT
	PUSHJ P,BPRJ
	POP P,A		;REMAINDER

BPR1:	MOVEI C,12	;PRINT TEN DIGITS
	SOJL C,CPOPJ
	IDIV A,BASEX
	HRLM B,(P)
	PUSHJ P,BPR1+1
	JRST FP7A1	;PARTICULAR TYO FOR DIGIT

;IGNORE LEADING ZERO DIGITS FOR FIRST WORD
BPR2:	JUMPE A,CPOPJ
	IDIV A,BASEX
	HRLM B,(P)
	PUSHJ P,BPR2
FP7A1:	HLRE A,(P)
	ADDI A,"0"
	JRST (R)	;PARTICULAR TYO FOR DIGIT

PAGE
;DIVIDES BIGNUM IN A BY INTEGER IN B
;DESTROYS ORIGINAL BIGNUM
;RETURNS REMAINDER IN A, QUOTIENT IN B
Q1:	MOVEM B,Y#
	PUSH P,A
	HRRZ A,(A)
	JUMPE A,Q1A
	PUSHJ P,Q1+1
	POP P,C
	HRRM B,(C)
	HLRZ T,(C)
	MOVE B,(T)
	DIV A,Y
Q1B:	MOVEM A,(T)	;REPLACE OLD DIGIT
	MOVE A,B
	MOVE B,C
	POPJ P,

Q1A:	POP P,C
	HLRZ T,(C)
	MOVE A,(T)
	IDIV A,Y
	JUMPN A,Q1B	;NON-ZERO QUOTIENT - KEEP IT
	HRRZM FF,(T)	;RECLAIM FULL WORD
	MOVE FF,T
	HRRZM F,(C)	;RECLAIM FREE WORD
	HRRZ F,C
	MOVEI C,0
	JRST Q1B+1
PAGE
;BIGNUM READ
;NUM3 IN LISP HAS JFCL 10,RDBNM
RDBNM:	PUSH P,[NIL]	;INITIAL VALUE OF BIGNUM
	MOVSI C,700
	HRRI C,(SP)	;BYPE POINTER TO SPEC PDL
	MOVEM T,TSAV#
	MOVEM C,RDPTR#
	HRRZ B,NUM1	;BASE OF NUMBER
	PUSHJ P,PWR10

RDNM1:	MOVEI C,12	;TEN DIGITS AT A TIME
	MOVEI A,0
	ILDB B,RDPTR
	JUMPE B,RDNM2	;END OF BIGNUM
	IMUL A,BASEX
	ADDI A,-"0"(B)
	SOJG C,.-4
	MOVE B,BASE10
	PUSHJ P,RDSUB
	JRST RDNM1

RDNM2:	CAIN C,12	;NO DIGITS IN LAST SUPERDIGIT
	JRST RDNM3
	HRREI C,-12(C)	;NUMBER OF DIGITS IN LAST
	MOVEI B,1
	IMUL B,BASEX
	AOJL C,.-1	;COMPUTE BASEX^(NUMBER OF DIGITS)
	PUSHJ P,RDSUB
RDNM3:	MOVEI B,POSNUM
	MOVE T,TSAV
	TLNE T,MINSGN	;SIGN OF BIGNUM
	MOVEI B,NEGNUM
	POP P,A
	SUB P,[XWD 1,1]
	JRST QCONS

RDSUB:	MOVE C,-1(P)
	PUSHJ P,BTIME1	;BIGNUM(C)*INT(B)+INT(A)
	MOVEM A,-1(P)
	POPJ P,
PAGE
BTIME0:	PUSH P,B
	PUSHJ P,COPY
	MOVE C,A
	POP P,B
	MOVEI A,0

;BIG(C)*INT(B)+INT(A) 
BTIME1:	JUMPE C,BNCONS	;END OF BIGNUM
	MOVEM B,MULR#	;MULTIPLIER
	PUSH P,C	;BIGNUM
BT1B:	MOVEM A,CARRY#
	MOVS T,(C)
	MOVE A,(T)
	MUL A,MULR
	ADD B,CARRY
	TLZE B,SIGN
	ADDI A,1
BT1E:	MOVEM B,(T)	;STORE LOW ORDER PRODUCT+CARRY IN BIGNUM
	HLRZS T		;(CDR BIGNUM)
	JUMPE T,BT1C	;END OF BIGNUM
	MOVE C,T
	JRST BT1B

BT1C:	JUMPE A,POPAJ	;NO HIGH ORDER PART 
	PUSHJ P,BNCONS	;CONSES FOR REMAINING HIGH ORDER PART
	HRRM A,(C)	;RPLACD END OF BIGNUM
POPAJ:	POP P,A
CPOPJ:	POPJ P,
PAGE
;BIGNUM COPY
COPY:	JUMPE A,CPOPJ
	HLRZ B,(A)
	PUSH P,(B)
	HRRZ A,(A)
	PUSHJ P,COPY
	MOVE B,A
	POP P,A
	JRST BCONS


;BIGNUM RECLAIM
RECLAIM:	
	CAILE A,INUMIN
	POPJ P,
	EXCH A,F
	EXCH A,(F)
	HRRZS A
	EXCH A,F
	EXCH A,(F)
	HLRZ B,A	;TYPE
	HRRZS A
	CAIE B,POSNUM
	CAIN B,NEGNUM
	JRST UNCONS
	POPJ P,

;BIGNUM UNCONS
UNCONS:
	JUMPE A,CPOPJ
	HLRZ B,(A)
	MOVEM FF,(B)
	MOVE FF,B
	EXCH A,F
	EXCH A,(F)
	HRRZS A
	JRST UNCONS

;EVBIG IN LISP HAS JRST BIGEV
BIGEV:	CAIE TT,POSNUM
	CAIN TT,NEGNUM
	POPJ P,
	HRRZ AR1,(AR1)
	JRST EVBIG+1
PAGE
;BIGNUM MINUSP
MINSP2:	CAIN B,POSNUM
	JRST FALSE
	JRST TRUE

;BIGNUM MINUS
MINS2:	CAIN B,POSNUM
	SKIPA B,[NEGNUM]
ABS2:	MOVEI B,POSNUM	;BIGNUM ABS
	JRST QCONS

;COMPARE TWO BIGNUMS A<B
BCMPR:	PUSHJ P,BDIF
	PUSH P,A
	PUSHJ P,MINUSP
	EXCH A,(P)
	PUSHJ P,RECLAIM
	JRST POPAJ

BEQUAL:	PUSHJ P,BDIF
	POP P,C
	CAIN A,INUM0
	JRST TRUE
	MOVE P,C
	PUSHJ P,RECLAIM
	JRST FALSE
PAGE
;DIFFERENCE OF TWO BIGNUMS
BDIF:	PUSHJ P,COMPSN	;COMPLEMENT SIGN OF BIGNUM IN B
;SUM OF TWO BIGNUMS
;BIGNUMS IN A AND B; SIGN(A) IN T, SIGN(B) IN TT
BPLUS:	PUSH P,B
	PUSHJ P,COPY
	EXCH A,(P)
	PUSHJ P,COPY
	POP P,C
	MOVE B,A
	MOVEI A,0
	CAME T,TT
	JRST BDIF1	;SIGNS DIFFERENT
	PUSH P,T	;SIGN OF RESULT
	PUSHJ P,BADD
	POP P,B
	JRST QCONS

BDIF1:	CAIN TT,POSNUM
	EXCH B,C
	PUSHJ P,BSUB	;POSNUM IN C, NEGNUM IN B
	JUMPL B,BDIF3
	PUSHJ P,SUPRSS
	MOVEI B,POSNUM
	JRST MAKBIG

BDIF3:	PUSHJ P,COMPLM
	MOVEI B,NEGNUM
	JRST MAKBIG

BSUB:	MOVNI TT,1
	MOVSI T,(SUB TT,(B))
	JRST BAS

BADD:	MOVEI TT,1
	MOVSI T,(ADD TT,(B))
PAGE
;CRY(A)(+ OR -) BIG(B) + BIG(C)  A, SIGN  B.
;DESTROYS BOTH BIGNUMS

BAS:	HRRM TT,BCRY
	PUSH P,B
BP2A:	HRRM B,BTMP
	MOVS B,(B)
	HLRZ TT,(C)
	EXCH TT,FF
	EXCH TT,(FF)	;RECLAIM FULL WORD
	EXCH C,F
	EXCH C,(F)	;RECLAIM FREE WORD
	ADD TT,A
	XCT T		;BIG(C) (+ OR -) BIG (B)
	MOVEI A,0
	TLZE TT,SIGN	;TURN OFF HIGH BIT
BCRY:	HRREI A,.	;SET CARRY IF OVERFLOW OR NEGATIVE
BP2B:	MOVEM TT,(B)
	HLRZS B
	HRRZS C
	JUMPE B,BP2F	;END OF B
	JUMPN C,BP2A
	JRST BP2D	;FINISH WITH CARRY (+ OR -) BIG(B)

BP2F:	JUMPE C,BP2H	;END OF C ALSO
	EXCH B,C
	HRRM B,@BTMP	;RPLACD END OF BIG(B) WITH REST OF C
	MOVSI T,(ADD TT,(B))	;FINISH WITH BIG(C) + CARRY
BP2D:	HRRM B,BTMP
	MOVS B,(B)
	MOVE TT,A
	XCT T		;CARRY (+ OR -) INTEGER
	JUMPL TT,BP2K
	MOVEM TT,(B)
	CAME T,[SUB TT,(B)]
	JRST POSXIT	;CAN QUIT NOW
	MOVEI A,0	;TURN OFF CARRY
	JRST BP2L	;CONTINUE TO NEGATE

BP2K:	HRRE A,BCRY
	TLZ TT,SIGN	;MAKE HIGH BIT ZERO
	MOVEM TT,(B)
BP2L:	HLRZS B
	JUMPN B,BP2D
BP2H:	JUMPLE A,XIT	;NO CARRY
	PUSHJ P,BNCONS
BTMP:	HRRM A,.	;RPLACD END OF BIGNUM WITH CARRY
POSXIT:	MOVEI B,0	;SIGN POSITIVE
	JRST POPAJ

XIT:	MOVE B,A	;SIGN IN B
	JRST POPAJ
PAGE
;SUPPRESS LEADING ZEROS FROM BIGNUM
SUPRSS:	SKIPA C,[JRST COMPL7]
;COMPLEMENT BIGNUM  (2^35 COMPLEMENT)
COMPLM:	MOVSI C,(SUBM T,(B))
	JUMPE A,CPOPJ
	PUSH P,A
	HRLZI T,SIGN
	MOVEI TT,0
COMPL4:	MOVS B,(A)
	SKIPN (B)
	JUMPE TT,COMPL3
	XCT C
	HRLOI T,SIGN-1
COMPL7:	SKIPE (B)
	MOVEM A,TT
COMPL3:	HLRZ A,B
	JUMPN A,COMPL4	;CONTINUE
	JUMPE TT,COMPL5	;ALL ZEROS
	HRRZ A,(TT)
	HLLZS (TT)	;RPLACD HIGH ORDER NON-ZERO WITH NIL
COMPL6:	PUSHJ P,UNCONS	;UNCONS LEADING ZEROS
	JRST POPAJ

COMPL5:	EXCH A,(P)
	JRST COMPL6

;SIGN(TT)SIGN(T)  TT
MQSIGN:	CAIN T,POSNUM
	JRST CPOPJ
;-SIGN(TT)  TT
COMPSN:	CAIN TT,POSNUM
	SKIPA TT,[NEGNUM]
	MOVEI TT,POSNUM
	POPJ P,
PAGE
;BIGNUM MULTIPLY
;BIG (A) * BIG (B)  A, SIGNS IN T,TT
BTIMES:	PUSHJ P,MQSIGN
	PUSH P,TT	;SAVE SIGN OF RESULT
	PUSHJ P,BMUL
	POP P,B
	JRST MAKBIG

;0(P) IS PARTIAL RESULT
;-1(P) IS REMAINING REVERSED MULTIPLIER
;-2(P) IS MULTIPLICAND

BMUL:	PUSH P,B
	PUSHJ P,REVERSE
	PUSH P,A
	MOVEI A,0
	PUSH P,A
BTLOOP:	SKIPN C,-1(P)
	JRST BTEND	;END OF MULTIPLIER
	JUMPE A,BTLP2	;FIRST TIME
	MOVE B,A
	PUSHJ P,FWCONS-1
	PUSHJ P,CONS	;INCREASE LENGTH OF PRODUCT
BTLP2:	MOVEM A,(P)
	MOVE A,-2(P)
	PUSHJ P,COPY
	MOVS B,(C)	;NEXT MULTIPLIER DIGIT
	MOVE C,A
	HLRZM B,-1(P)
	MOVE B,(B)
	MOVEI A,0
	PUSHJ P,BTIME1
	MOVE C,(P)
	JUMPE C,BTLOOP	;NO ADD NEEDED ON FIRST TIME
	MOVE B,A
	MOVEI A,0
	PUSHJ P,BADD
	JRST BTLOOP

BTEND:	SUB P,[XWD 3,3]
	JRST SUPRSS

PAGE
;EXTENSIONS OF INTERPRETER ROUTINES AND TESTS

;ADDITION TO NUMVAL. NUMV4 IN LISP CHANGED TO JRST NUMVB
NUMVB:	CAIE B,POSNUM
	CAIN B,NEGNUM
	JRST NUMVD2
	MOVE A,AR1
	JRST NUMV2	;PRINT ERROR MESSAGE

NUMVD2:	POP P,C		;ADDRESS OF (PUSHJ P,NUMVAL) +1
	HLRZ C,(C)
	CAIN C,(JUMPN A,)	;ZEROP
	JRST FALSE
	CAIN C,(JUMPGE A,)	;MINUSP
	JRST MINSP2
	CAIN C,(MOVNS)		;MINUS
	JRST MINS2
	CAIN C,(MOVMS)		;ABS
	JRST ABS2
	CAIN C,(CAIE B,)	;FIX
	JRST POPAJ
	HALT			;TEMPORARY
;EXTENSION TO NUMBERP.  NUMBRP4 IN LISP CHANGED TO JRST BIGNP
BIGNP:	CAIE A,POSNUM
	CAIN A,NEGNUM
	JRST TRUE
	JRST FALSE
PAGE
;EXTENSION TO OP.  OPOV IN LISP CHANGED TO JFCL 10,FIXOVL
FIXOVL:	HLRZ C,(C)
	CAIN C,(IMUL A,)
	JRST REMUL	;TIMES OVERFLOWED. RECOMPUTE
	TLC A,SIGN	;ALL OTHER CASES JUST OVERFLOWED 1 BIT
	MOVM B,A
	MOVE TT,A
	MOVEI A,1
	PUSHJ P,MKBG
	JRST QCONS

REMUL:	MOVE A,AR1
	MOVEI B,FIXNUM
	MOVEI T,FIXNUM
	PUSHJ P,BIGTST
	JRST BTIMES	;USE THE BIGNUM MULTIPLICATION

;EXTENSION TO OP.  NUMV3 CHANGED TO JRST BIGDIS
;BIGDIS DETERMINES THE BIGNUM OPERATION TO BE PERFORMED
BIGDIS:	CAIE T,FLONUM
	CAIN B,FLONUM
	JRST FLOBIG	;OPERATION WITH FLT PT OPERAND
	PUSHJ P,BIGTST	
	HLRZ C,(C)
	CAIN C,(ADD A,)	;PLUS
	JRST BPLUS
	CAIN C,(SUB A,)	;DIF
	JRST BDIF
	CAIN C,(IMUL A,)	;TIMES
	JRST BTIMES
	CAIN C,(IDIV A,)	;QUOTIENT
	JRST BQUO
	CAIN C,(JRST)		;LESSP OR GREATERP
	JRST BCMPR
	CAIN C,(JUMPN 0,)	;DIVIDE
	JRST BDIV
	CAIN C,(JUMPA)		;GCD
	JRST GCD
	CAIN C,(JUMPL)		;EQUAL
	JRST BEQUAL
	HALT			;TEMPROARY
PAGE
;TRANSFORMS GENERAL NUMBERS IN (A,T),(TT,B)
;INTO BIGNUMS IN (A,T),(B,TT), VALUES IN A,B; SIGNS IN T,TT.
BIGTST:	EXCH B,T	;FUNNY AC USAGE IN LISP
	PUSH P,T
	PUSH P,TT
	PUSHJ P,BIGSUB	;CONVERT NUMBER ORIGINALLY IN A,T
	EXCH B,-1(P)
	EXCH A,(P)
	PUSHJ P,BIGSUB	;CONVERT NUMBER ORIGINALLY IN TT,B
	MOVE TT,B
	MOVE B,A
	POP P,A
	POP P,T
	POPJ P,

BIGSUB:	CAIE B,POSNUM
	CAIN B,NEGNUM
	POPJ P,		;NO CONVERSION NECESSARY
	CAIE B,FIXNUM
	JRST NUMV2	;CHECK FOR FLONUM
	MOVEI B,0
	MOVE TT,A	;GET VALUE OF NUMBER
	MOVM A,TT
	JUMPGE A,BIGSRT	
	MOVEI A,1	;BASTARD CASE OF -2^35
MKBG:	PUSHJ P,MKBIG
	JRST BIGSND

BIGSRT:	PUSHJ P,BCONS
BIGSND:	SKIPGE TT
	SKIPA B,[NEGNUM]
	MOVEI B,POSNUM
	POPJ P,

MKBIG:	PUSH P,B
	PUSHJ P,BNCONS
	MOVE B,A
	POP P,A
	JRST BCONS
PAGE
;MAKE A LISP NUMBER FROM BIGNUM -- A IS LIST, B IS SIGN
MAKBIG:	JUMPE A,FIX1A	;NULL LIST PRODUCES ZERO
	HRRZ C,(A)
	JUMPN C,QCONS		;A REAL BIGNUM
	HLRZ C,(A)		;ONLY ONE WORD OF PRECISION
	MOVE C,(C)
	CAIE B,POSNUM
	MOVNS C			;NEGATIVE 
	PUSHJ P,UNCONS
	MOVE A,C
	JRST FIX1A
PAGE
FLOBIG:	CAIE T,FLONUM
	JRST FLBG2
	MOVE A,(A)
	EXCH A,TT
	EXCH B,T
	PUSHJ P,BFLT
	EXCH A,TT
	JRST OPR

FLBG2:	PUSHJ P,BFLT
	MOVE TT,(TT)
	JRST OPR

;MAKE A FLOATING PT NUMBER OUT OF A BIGNUM
BFLT:	PUSH P,C
	PUSH P,T
	CAIE T,POSNUM
	CAIN T,NEGNUM
	SKIPA T,[-200]
	JRST NUMV2
BFLT2:	MOVE C,B
	HLRZ B,(A)
	HRRZ A,(A)
	ADDI T,43
	JUMPN A,BFLT2	;FIND LAST TWO WORDS OF BIGNUM
	MOVE B,(B)
	MOVE C,(C)
BFLT3:	TLNE B,SIGN/2
	JRST BFLT4
	ASHC B,1
	SOJA T,BFLT3	;NORMALIZE B,C
BFLT4:	JUMPGE T,FLOOV
	ASH B,-10
	DPB T,[POINT 8,B,8]
	MOVE A,B
	POP P,T
	POP P,C
	CAIE T,POSNUM
	MOVNS A
	POPJ P,

;MAKE A BIGNUM FROM A FLT PT NUMBER
BFIX:	MOVE A,(P)
	PUSHJ P,NUMVAL
	MOVMS A
	MULI A,400
	MOVEI C,-243(A)	;#LEFT SHIFTS NEEDED
	IDIVI C,43	;C_#EXTRA WORDS-1, D_#SHIFTS
	MOVEI A,0
	ASHC A,(C+1)
	PUSH P,B
	PUSHJ P,BNCONS
	MOVE B,A
	POP P,A
	PUSHJ P,BCONS
	SOJL C,BFIX2
	MOVE B,A
	MOVEI A,0
	PUSHJ P,BCONS
	SOJGE C,.-3
BFIX2:	POP P,TT
	PUSHJ P,BIGSND
	JRST QCONS

PAGE
;BIGNUM DIVIDE
BDIV:	PUSHJ P,MQSIGN	;COMPLEMENT SIGN OF TT IF T IS NEGNUM
	PUSH P,T	;SIGN OF REMAINDER
	PUSH P,TT	;SIGN OF QUOTIENT
	PUSHJ P,DIVSUB
BDIV2:	EXCH B,(P)
	PUSHJ P,MAKBIG	;QUOTIENT
	MOVE B,-1(P)
	MOVEM A,-1(P)
	POP P,A
	PUSHJ P,MAKBIG	;REMAINDER
	POP P,B
	JRST XCONS

BQUO:	PUSHJ P,MQSIGN
	PUSH P,TT
	PUSHJ P,DIVSUB
	PUSH P,A
	MOVE A,B
	PUSHJ P,UNCONS
	POP P,A
	POP P,B
	JRST MAKBIG

DIVSUB:	HRRZ C,(B)
	JUMPN C,DIV1
;NULL(CDR B) MEANS SINGLE LENGTH DIVISOR
BQUO1:	PUSH P,B
	PUSHJ P,COPY
	POP P,B
	HLRZ B,(B)
	MOVE B,(B)
	PUSHJ P,Q1
	PUSH P,B	;QUOTIENT
	PUSHJ P,BNCONS
	MOVE B,A
	JRST POPAJ

PAGE
;DIV1 DOES LONG DIVISION OF X/Y 
;ENTER WITH X IN A, Y IN B.
DIV1:	PUSH P,A	;X
	PUSH P,B	;Y
	MOVE A,B
	PUSHJ P,HIDIG
	HRLOI A,SIGN/2-1
	IDIV A,(C)	;(BETA/2-1)/Y[N-1]+1
	ADDI A,1
	MOVEM A,SCALE#
	MOVE B,A
	MOVE A,(P)	;Y - DIVISOR
	PUSHJ P,BTIME0	;SCALE*Y
	MOVEM A,V	;SCALED DIVISOR
	MOVEM A,(P)	;PROTECT V FROM GC
	PUSHJ P,HIDIG
	POP C,VH	;V[N-1]
	POP C,VH1	;V[N-2]
	MOVE A,-1(P)	;X - NUMERATOR
	PUSHJ P,COPY
	PUSHJ P,EXTND
	MOVE B,SCALE
	MOVE C,A
	PUSHJ P,BTIME1-1	;SCALE*X  -- SCALED NUMERATOR
	MOVEM A,-1(P)	;U
	PUSH P,[NIL]	
	HRRZM P,QUO#	;POINTER TO QUOTIENT LIST
	PUSHJ P,LENGTH
	PUSH P,A
	MOVE A,V#
	PUSHJ P,LENGTH
	POP P,B
	SUB B,A		;LENGTH(U)-LENGTH(V)
	MOVE A,-2(P)	;U
	JUMPLE B,DIV1X	;SPECIAL CASE OF U<V
	PUSHJ P,DIV2	;CARRY OUT DIVISION WITH PARAMETERS
DIV1X:	PUSHJ P,SUPRSS	;SUPPRESS LEADING ZEROS OF REMAINDER
	JUMPE A,DIV1Y	;ZERO REMAINDER
	MOVE B,SCALE
	PUSHJ P,Q1	;U/SCALE - FINAL REMAINDER IN B
	MOVE A,B
DIV1Y:	EXCH A,(P)
	PUSHJ P,SUPRSS	;SUPPRESS LEADING ZEROS IN QUOTIENT
	POP P,B
	SUB P,[XWD 2,2]
	POPJ P,

;RECURSIVE FUNCTION TO POSITION V PROPERLY WITH RESPECT TO U.
; ON SUCCESSIVE CALLS TO DIV3 WHICH CALCULATES QUOTIENT DIGITS.
;ENTER DIV2 WITH U IN A, N IN B. N= LENGTH(U)-LENGTH(V)-1.

DIV2:	SOJLE B,DIV3
	PUSH P,A	;U
	HRRZ A,(A)
	PUSHJ P,DIV2
	HRRM A,@(P)	;(RPLACD U,(DIV3(CDR U)))
	POP P,A
	JRST DIV3
PAGE
;ENTER WITH U[J] IN A

DIV3:	PUSH P,A	;UJ
	PUSHJ P,HIDIG
	POP C,A		;UH
	CAML A,VH#
	JRST DIVCS1	;STRANGE CASE WHEN UHVH
	POP C,B		;UH1
	DIV A,VH	;(UH*BETA+UH1)/VH
	PUSH P,A	;QUOTIENT DIGIT
L1:	MOVEM B,REM#	;REMAINDER
	MUL A,VH1#
	SUB A,REM	;(VH1*QUO)-BETA*REM
	CAMGE B,(C)	;UH2
	SUBI A,1
	JUMPG A,DIVCS2	;QUOTIENT TOO BIG
L4:	MOVE A,V
	MOVE B,(P)	;QUOTIENT DIGIT
	PUSHJ P,BTIME0	;Q*V
	MOVE C,-1(P)	;UJ
	MOVE B,A
	MOVEI A,0
	PUSHJ P,BSUB	;UJ-Q*V
	JUMPL B,DIVCS3	;QUOTIENT TOO BIG
L3:	MOVEM A,-1(P)	;NEW UJ
	POP P,A		;QUOTIENT DIGIT
	MOVE B,@QUO
	PUSHJ P,BCONS
	MOVEM A,@QUO	;NEW QUOTIENT LIST
	MOVE A,(P)
	PUSHJ P,DIVSRT	;SHORTEN UJ BY ONE DIGIT
	JRST POPAJ
PAGE
;SPECIAL CASE OF UHVH
DIVCS1:	HRLOI A,SIGN-1		;BETA-1
	PUSH P,A
	POP C,B		;UH1
	ADD B,VH	;R_UH1+VH
	JUMPL B,L4
	JRST L1

;SPECIAL CASE CORRECTION FOR QUOTIENT
DIVCS2:	SOS A,(P)		;QUOTIENT_QUOTIENT-1
	MOVE B,REM
	ADD B,VH	;R_R+VH
	JRST L1

;SPECIAL CASE OF QUOTIENT TOO LARGE
DIVCS3:	SOS (P)		;QUOTIENT_QUOTIENT-1
	PUSH P,A
	MOVE A,V
	PUSHJ P,COPY
	MOVE C,A
	POP P,B
	MOVEI A,0
	PUSHJ P,BADD	;U_U+V
	MOVEM A,-1(P)
	PUSHJ P,DIVSRT	;SHORTEN OVERFLOWED DIGIT
	JRST L3+1
PAGE
;PUSHES SUCCESSIVE DIGITS OF LIST IN A ONTO PDL
;RETURNS C POINTING TO PDL LOCATION OF LAST DIGIT
HIDIG:	MOVE C,P
	MOVS B,(A)
	PUSH P,(B)
	HLRZ A,B
	JUMPN A,HIDIG+1
	EXCH C,P
	POPJ P,

;SHORTEN LIST BY ONE
DIVSRT:	MOVE C,A
	HRRZ A,(A)
	HRRZ B,(A)	;CDDR
	JUMPN B,.-3
	HLLZS (C)	;NULL (CDDR C) => RPLACD(C NIL)
	HLRZ B,(A)
	JRST UNCONS

;LENGTHEN LIST BY ONE
EXTND:	PUSH P,A
	PUSHJ P,LAST
	MOVE T,A
	PUSHJ P,B0CONS
	HRRM A,(T)
	JRST POPAJ
PAGE
GA==4
GB==5
GC==6
GD==7
UP==10
VP==11
Q==12
;BIGNUM GCD
GCD:	PUSH P,B
	PUSHJ P,COPY
	EXCH A,(P)	;V
	PUSHJ P,COPY
	PUSH P,A	;U
	PUSHJ P,COPY
	MOVE C,A
	MOVE A,-1(P)	
	PUSHJ P,COPY
	MOVE B,A	;U
	MOVEI A,0
	PUSHJ P,BSUB	;V-U
	PUSH P,B
	PUSHJ P,BSUBND
	JUMPE A,GCDSC1	;U=V
	PUSHJ P,UNCONS
	POP P,B
	JUMPGE B,GCD2	;UV
	MOVE A,(P)
	EXCH A,-1(P)
	MOVEM A,(P)
PAGE
;NOW V<U   V IN -1(P), U IN (P)
GCD2:	MOVE A,-1(P)
	JUMPE A,GCDEND	;V IS ZERO
	HRRZ B,(A)
	JUMPE B,GCDSING	;V IS SINGLE PRECISION
	PUSHJ P,LENGTH	;LENGTH (V)
	MOVE T,A
	MOVE A,(P)	;U
	PUSHJ P,LENGTH
	SUB A,T		;L(U)-L(V)
	JUMPE A,GCD4
	SOJN A,GCD7A	;>1
	MOVE A,-1(P)	;V
	PUSHJ P,EXTND	;LENGTHEN V BY ONE HIGH ORDER ZERO
GCD4:	MOVE A,(P)	;U
	PUSHJ P,HIDIG
	HRLOI A,SIGN/2-1	;BETA/2-1
	IDIV A,(C)	;(BETA/2-1)/U[N-1]+1
	ADDI A,1
	MOVEM A,SCALE
	PUSHJ P,GCSB
	MOVE UP,A	;SCALE*UH
	MOVE A,-1(P)	;V
	PUSHJ P,HIDIG
	PUSHJ P,GCSB
	MOVE VP,A	;SCALE*VH
	MOVEI GA,1
	MOVEI GD,1
	SETZB GC,GB
PAGE
GCD5:	MOVE A,UP
	ADD A,GA
	MOVE B,VP
	ADD B,GC
	JUMPE B,GCD7
	JUMPL A,GCD5X	;OVERFLOW CASE
	IDIV A,B	;(U'+A)/(V'+C)
GCD5A:	MOVE Q,A
	MOVE A,UP
	ADD A,GB
	MOVE B,VP
	ADD B,GD
	JUMPE B,GCD7
	SKIPG B
	TDZA A,A	;SPECIAL CASE OF V'+D = BETA
	IDIV A,B	;(U'+B)/(V'+D)
	CAME A,Q
	JRST GCD7
	MOVE A,GC
	EXCH GA,GC	;A'_C
	IMUL A,Q
	SUB GC,A	;C'_A-Q*C
	MOVE A,GD
	EXCH GB,GD	;B'_D
	IMUL A,Q	
	SUB GD,A	;D'_B-Q*D
	MOVE A,VP
	EXCH UP,VP	;UP'_VP
	IMUL A,Q
	SUB VP,A	;VP'_UP-Q*VP
	JRST GCD5
PAGE
;SPECIAL CASE WHEN U'+A=BETA
GCD5X:	MOVEI A,1
	MOVE C,B
	MOVEI B,0
	DIV A,C
	JRST GCD5A

GCD7:	JUMPE GB,GCD7A
	MOVE A,(P)	;U
	MOVE B,-1(P)	;V
	PUSH P,GC
	PUSH P,GD
	PUSHJ P,GCDSB	;A*U+B*V
	POP P,GB
	POP P,GA
	EXCH A,(P)	;U
	MOVE B,-1(P)
	PUSHJ P,GCDSB	;C*U+D*V
	MOVEM A,-1(P)	;V
	JRST GCD2

GCDSB:	PUSH P,GA
	PUSH P,GB
	PUSH P,B
	MOVM B,GA
	PUSHJ P,BTIME0
	EXCH A,(P)	;B
	MOVM B,-1(P)	;GB
	PUSHJ P,BTIME0
	POP P,B	;A*GA
	POP P,GA
	POP P,GB
	XOR GA,GB
	MOVE C,A
	MOVEI A,0
	JUMPGE GA,BADD	;SIGNS SAME
	PUSHJ P,BSUB	;SIGNS DIFFERENT
BSUBND:	JUMPGE B,SUPRSS
	JRST COMPLM

GCD7A:	MOVE A,-1(P)
	PUSHJ P,SUPRSS
	MOVE B,A
	MOVE A,(P)
	PUSHJ P,DIV1	;U/V
	EXCH B,-1(P)	;V_REMAINDER
	MOVEM B,(P)	;U_V
	PUSHJ P,UNCONS	;DONT NEED QUOTIENT
	JRST GCD2
PAGE
GCDSING:	
	POP P,A	;U
	MOVE B,(P)	;V - SINGLE PRECISION
	HLRZ B,(B)
	MOVE B,(B)
	MOVEM B,(P)
	PUSHJ P,Q1	;U MOD V  A
	POP P,B		;A < B
	JUMPE A,GCDS2
;SINGLE PRECISION GCD
	IDIV B,A
	MOVE B,A
	MOVE A,C
	JUMPN A,.-3
GCDS2:	MOVE A,B
	JRST FIX1A

GCSB:	MOVE A,-1(C)
	MUL A,SCALE
	MOVE B,A
	MOVE A,(C)
	IMUL A,SCALE
	ADD A,B
	POPJ P,
PAGE
GCDSC1:	SUB P,[XWD 2,2]
	POP P,A
	MOVEI B,POSNUM
	JRST MAKBIG

GCDEND:	POP P,A	;U IS RESULT
	SUB P,[XWD 1,1]
	MOVEI B,POSNUM
	JRST MAKBIG

	END