Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-06 - decus/20-153/sqrt.mac
There is 1 other file named sqrt.mac in the archive. Click here to see a list.
	TITLE	SQRT for RPGLIB V1
	SUBTTL	Square root and floating point routines


;	SQRT for RPGLIB V1
;
;
;	This module contains the square root routine along with other
;	miscellaneous floating point routines.
;
;	Copyright (C) 1976, Bob Currier and Cerritos College
;	All rights reserved
;
;

	SEARCH	RPGPRM, UUOSYM, MACTEN

	%%LBLP==:%%LBLP
	DEBUG==:DEBUG
	BIS==:BIS

	SALL

	TWOSEG
	RELOC	400000


	ENTRY	SQRT.			; square root routine
	ENTRY	FLOT.1			; float a single precision integer
	ENTRY	FLOT.2			; float a double precision integer
	ENTRY	FIX.			; fix a double precision integer


	PR==15
	NM==5
	AC0==0
	AC1==1
	G==T2
	H==T3
;SQRT.		Main square root routine
;
;Uses Newton's method
;
;

SQRT.:	JUMPL	AC1,SQRT.1		; must be positive
	MOVE	G,AC1			; get arg
	FDVR	G,[2.0]			; get a guess

SQ.1:	MOVE	H,AC1			; get arg
	FDVR	H,G			; get H/G
	FAD	H,G			; get G+(H/G)
	FDVR	H,[2.0]			; get (G+(H/G))/2
	MOVE	T1,H			; get it where we can play with it
	FSB	T1,G			; get difference
	TLNN	T1,377000		; get it to nearest 1e-127
	  JRST	SQ.2			; yes -
	MOVE	G,H			; no get new guess
	JRST	SQ.1			; and loop

SQ.2:	MOVE	AC1,H			; get result into proper AC
	POPJ	PP,			; and exit

SQRT.1:	PUSHJ	PP,%%H.11##		; square root of negative number illegal
	SETZ	AC1,			; return 0 on continue
	POPJ	PP,			; exit
;FIX.		Convert floating point to double precision fixed point
;
;Calling sequence:
;
;	MOVE	AC,[floating.point.number]
;	MOVE	16,[Z AC,result.address]
;	PUSHJ	17,FIX.
;
;

FIX.:	LDB	T1,[POINT 4,PARM,12]	; get the AC
	MOVE	T1,(T1)			; get the floating point number
	TDNN	T1,[XWD 777,777777]	; is it zero?
	  JRST	CC3C2D			; yes -
	MOVM	T2,T1			; no -
	MULI	T2,400			; get exponent
	MOVEI	T4,0			; zap
	ASHC	T3,-306(T2)		; shift to get integer
	JUMPGE	T1,CC3C2C		; jump if input was positive
	SETCA	T3,			; else negate the two word result
	MOVNS	T4			; complement and increment
	SKIPN	T4			; zero?
	  ADDI	T3,1			; yes - increment
	SKIPGE	T3
	  TLO	T4,1B18			; set sign bit if necessary

CC3C2C:	MOVEM	T3,0(PARM)		; stash result
	MOVEM	T4,1(PARM)		; both parts
	POPJ	PP,			; exit

CC3C2D:	SETZM	0(PARM)			; input is zero - give zero result
	SETZM	1(PARM)			; double precision
	POPJ	PP,			; exit
;FLOT.1		Convert single precision fixed point to floating point
;
;Calling sequence:
;
;	MOVE	16,[Z AC,operand]
;	PUSHJ	17,FLOT.1
;
;Exit with result in accumulator specified by AC field of 16
;
;

FLOT.1:	SKIPN	NM,0(PARM)		; is input zero?
	  JRST	FLOT1A			; yes -
	IDIVI	NM,1B18			; no - break it into two pieces
	CAIE	NM,0			; high part zero?
	  TLC	NM,254000		; no - jam exponent
	TLC	NM+1,233000		; jam exponent of low part
	FADR	NM,NM+1			; add two halves

FLOT1A:	LDB	T2,[POINT 4,PARM,12]	; get AC field
	MOVEM	NM,0(T2)		; store result
	POPJ	PP,			; and exit
;FLOT.2		Convert double precision fixed point number to floating point
;
;Calling sequence:
;
;	MOVE	16,[Z AC,ADDRESS.OF.HIGH.ORDER.HALF.OF.FIXED.POINT.NUMBER]
;	PUSHJ	17,FLOT.2
;
;Exit with result in AC specified by AC field of 16
;
;

FLOT.2:	MOVE	PR,[1.0]		; set scaling factor
	MOVE	T2,1(PARM)		; get low order
	SKIPL	T1,0(PARM)		; get high order part - is it negative?
	  JRST	FLOT2B			; no -
	TLO	T2,1B18			; yes - be sure low part is negative also
	SETCA	T1,			; negate the two word value
	MOVMS	T2			; get magnitude
	TLZ	T2,1B18			; reset sign bit
	JUMPN	T2,FLOT2C		; zero?
	AOJA	T1,FLOT2C		; yes - bump and jump

FLOT2B:	TLZ	T2,1B18			; make sure low part is positive

FLOT2C:	TLNE	T1,377776		; is value > 2**54 ?
	  JRST	FLOT2E			; yes -
	ASHC	T1,10			; no - shift over 8 bits
	ASH	T2,-10			; restore low part
	SKIPE	T1			; set exponent in high part unless
	  TLC	T1,266000		;   it is zero
	SKIPE	T2			; set exponent in low part unless
	  TLC	T2,233000		;   it is negative
	FADR	T1,T2			; add two halves
	FMP	T1,PR			; multiply by scaling factor
	SKIPGE	0(PARM)			; was input negative?
	  MOVNS	T1			; yes - negate result
	LDB	T2,[POINT 4,PARM,12]	; get AC field
	MOVEM	T1,0(T2)		; store result
	POPJ	PP,			; exit

FLOT2E:	ADD	PR,[1B8]		; number > 2**54 - increase scaling factor
	ASHC	T1,-1			; reduce T1
	JRST	FLOT2C			; try again


	END