@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             MFN011
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
~V2 -16
                                                                  ISSUE 8~
~V2 0
~V9 -1
~P
~V9 1
~YMFN011
~S1~M~LMATHEMATICAL LIBRARY IMPLEMENTATION DESCRIPTION
~S1~M~LSection 1 Version 1
~S1~LSection 1.1 Mathematical Functions
~S1~L1. General Description
~BThis section provides machine independent procedures for single
precision (32 bit)
mathematical functions.
~BThe algorithms are set up for floating point numbers with a
base of 2 or 16. To compile the library for base 2 operation,
all lines starting ::BASE2 must be included. This is done by editing
the file before compilation to remove all ::BASE2.
~BSimilarly, to compile the library for base 16 operation all lines
starting ::BASE16 must be included. A pre-compilation edit to
remove all ::BASE16 will achieve this.
~BThe Mathematical Library is initially an adaptation of a set of MU5
mathematical functions. Some of the single precision functions are
therefore more precise than necessary. It is hoped to "tune" all
single precision functions to 32 bit at a later date. The complex
functions are also more precise than necessary and will be adjusted later.
~Q 22
~S1~L2. Interfaces~
~
Mathematical Library Procedures:~
~
~LSingle Precision (32 bit)~
   EXP~
   LOG~
   SIN~
   COS~
   TAN~
   ASIN~
   ACOS~
   ATAN~
   SINH~
   COSH~
   TANH~
   SQRT~
   RPOWER~
   IPOWER~
   POWER~
   ATAN2~
   LOG~
~
Other Modules Used:~
   Section  0:   (Configuration)~
~S1~L2.1 Hardware Interface
~S1~L2.2 Software Interface
~S11) EXP(X)RESULT
~BReturns e*. Based on algorithm 1305 in "Computer Approximations"
by Hart et.al.
~S12) LN(X)RESULT
~BReturns the natural logorithm of X. Based on algorithm 2665 in
Hart et.al. (see EXP).
~S13) SIN(X)RESULT
~BReturns the sin of X. Based on algorithm 3305 in Hart et.al.
(see EXP).
~S14) COS(X)RESULT
~BReturns cos X. Calls SIN(PI/2+X).
~S15) TAN(X)RESULT
~BReturns tan X. This is at present implemented by SIN(X)/COS(X).
This is not very efficient and may cause exponent overflow. It
will be rewritten at a future date.
~S16) ASIN(X)RESULT
~BReturns arcsin X in the range -P1/2 to P1/2. Implemented as ATAN[X/SQRT(1-X{2}
)].
~S17) ACOS(X)RESULT
~BReturns arcsin X in the range 0 to PI. Implemented as PI/2 - ASIN(X).
~S18) ATAN(X)RESULT
~BReturns arctan X. Based on algorithm 4903 in Hart et.al.
(see EXP).
~S19) SINH(X)RESULT
~BReturns sinh X. Implemented as (EXP(X)+EXP(-X))/2.
~S110) COSH(X)RESULT
~BReturns cosh X. Implemented as (EXP(X)-EXP(-X))/2.
~S111) TANH(X)RESULT
~BReturns tanh X.
~S112) SQRT(X)RESULT
~BReturns the square root of X. Implemented using an initial
approximation and four Newton iterations.
~S113) RPOWER(X,Y)RESULT
~BReturns X to the power of Y, where X and Y are floating point
numbers. Implemented as EXP(YLN(X)).
~S114) IPOWER(X,Y)RESULT
~BReturns X to the power of Y, where X is a floating point
number and Y an integer greater or equal to 0.
~S115) POWER(X,Y)RESULT
~BReturns X to the power of Y, where X and Y are integers
and Y is greater or equal to 0.
~S116) ATAN2(X,Y)RESULT
~BReturns arctan (X/Y).~
~S117) LOG(X)RESULT
~BReturns the logarithm to the base 10 of X.
~S1~L3. Implementation
~S1~L3.1 Outline of Operation
~S1~L3.2 Data Structures
~Y
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H                MFN011
~V9 -1
~F
@TITLE MFN01(1,11)
@COL 1S-2F
@FLOW 1-2
@BOX 1.0
SINGLE PRECISION
MATHMATICAL FUNCTIONS
@BOX 2.0
END
@BOX 1.1
PSPEC FORM.R($IN,$RE32)/$RE32;
PSPEC R.EXP($RE32)/$IN;
PSPEC R.MANT($RE32)/$RE32;
LSPEC ENTER.TRAP($IN,$IN);
IMPORT LITERAL MAX.EXP,MIN.EXP;
MODULE(EXP,LN,SIN,COS,TAN,ASIN,ACOS,ATAN,SINH,COSH,TANH,
        SQRT,RPOWER,IPOWER,POWER,ATAN2,LOG);
LSPEC EXP ($RE32  )/$RE32 ;
LSPEC LN ($RE32  )/$RE32 ;
LSPEC SIN ($RE32  )/$RE32 ;
LSPEC COS($RE32)/$RE32;
LSPEC TAN($RE32)/$RE32;
LSPEC ASIN($RE32)/$RE32;
LSPEC ACOS($RE32)/$RE32;
LSPEC ATAN($RE32)/$RE32;
LSPEC SINH($RE32)/$RE32;
LSPEC COSH($RE32)/$RE32;
LSPEC TANH($RE32)/$RE32;
LSPEC SQRT ($RE32  )/$RE32 ;
LSPEC ATAN2 ($RE32  ,$RE32  )/$RE32 ;
LSPEC RPOWER ($RE32  ,$RE32  )/$RE32 ;
LSPEC IPOWER ($RE32  ,$IN32  )/$RE32 ;
LSPEC LOG ($RE32  )/$RE32 ;
LSPEC POWER($IN32,$IN32)/$IN32;
LITERAL/$RE32    PIBY2    =    1.570796326794896;
#MFN01.1
#MFN01.2
#MFN01.3
#MFN01.4
#MFN01.5
#MFN01.6
#MFN01.7
#MFN01.8
#MFN01.9
#MFN01.10
#MFN01.11
#MFN01.15
#MFN01.16
#MFN01.17
#MFN01.18
#MFN01.19
#MFN01.20
@BOX 2.1
*END
@END



@TITLE MFN01.1(1,6)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
EXP(X)
@BOX 2.0
CODE FOR EXP
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC EXP( AA);
$IN I;
::BASE16 LITERAL /$RE32     LOGEBASE   =            -2.772588722239785  ;
::BASE2 LITERAL /$RE32   LOGEBASE   =   -0.693147180559945   ;
LITERAL /$RE32     P0   =             1.000000000000003  ;
LITERAL /$RE32     P1   =            -0.693147180559909  ;
LITERAL /$RE32     P2   =             0.240226506957616  ;
LITERAL /$RE32     P3   =            -0.055504108641562  ;
LITERAL /$RE32     P4   =             0.009618128920594  ;
LITERAL /$RE32     P5   =            -0.001333354936029  ;
LITERAL /$RE32     P6   =             0.000154032725291  ;
LITERAL /$RE32     P7   =            -0.000015247856434  ;
LITERAL /$RE32     P8   =             0.000001315585623  ;
LITERAL /$RE32     P9   =            -0.000000097197400  ;
LITERAL /$RE32     P10   =             0.000000005002211  ;
 IF       AA >= MAX.EXP, -> OVERFL;
 IF       AA =< MIN.EXP, -> UNDERFL;
  AA/LOGEBASE => AA  => I;
IF AA = 0. THEN 1. => EXP;EXIT FI
 IF   AA < 0. THEN
   1.->I;
 FI ;
 I  -: AA=>AA*P10+P9*AA+P8*AA
 +P7*AA+P6*AA+P5*AA+P4*AA+P3*AA+P2*AA+P1*AA+P0=>AA;
::BASE16 AA*AA=>AA*AA=>AA;
FORM.R(0.-I,AA) => EXP;
EXIT;
OVERFL: ENTER.TRAP(8,10);
UNDERFL:  0. => EXP;
END ;
@END
@TITLE MFN01.2(1,8)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
LN(X)
@BOX 2.0
CODE FOR LN
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC LN ( AA);
$RE32  EXP,CJ,CONST,XX;
IF   AA =< 0., -> OVERFL;
::BASE16 LITERAL /$RE32     LOGEBASE   =             2.772588722239785  ;
::BASE2 LITERAL /$RE32   LOGEBASE   =   0.693147180559945   ;
LITERAL /$RE32     B1   =             0.500000000000000  ;
LITERAL /$RE32     B2   =             0.250000000000000  ;
LITERAL /$RE32     B3   =             0.125000000000000  ;
::BASE16 LITERAL /$RE32     C1   =             0.707106781186547  ;
::BASE2 LITERAL /$RE32   C1   =   0.9170040432046722;
::BASE16 LITERAL /$RE32     C2   =             0.353553390593274  ;
::BASE16 LITERAL /$RE32     C3   =             0.176776695296637  ;
::BASE16 LITERAL /$RE32     C4   =             0.088388347648318  ;
LITERAL /$RE32     P0   =             2.000000000000003  ;
LITERAL /$RE32     P1   =             0.666666666663367  ;
LITERAL /$RE32     P2   =             0.400000001206045  ;
LITERAL /$RE32     P3   =             0.285714091590489  ;
LITERAL /$RE32     P4   =             0.222238233327911  ;
LITERAL /$RE32     P5   =             0.181113626796700  ;
LITERAL /$RE32     P6   =             0.169482124880000  ;
::BASE16 LITERAL /$RE32     CJ1   =            -0.346573590279973  ;
::BASE2 LITERAL /$RE32   CJ1   =   -0.086643397569993   ;
::BASE16 LITERAL /$RE32     CJ2   =            -1.039720770839917  ;
::BASE16 LITERAL /$RE32     CJ3   =            -1.732867951399864  ;
::BASE16 LITERAL /$RE32     CJ4   =            -2.426015131959811  ;
R.EXP(AA) => EXP;
R.MANT(AA) => AA;
::BASE16  IF   AA < B2, -> I43;
::BASE16  IF   AA < B1, -> I2;
  CJ1 => CJ;
  C1 => CONST;
 EVAL:
  CONST + AA /:  (AA-CONST) =>AA*AA=>XX*P6+P5*XX+P4*XX+P3*XX+P2*XX
 +P1*XX+P0*AA=>XX;
  LOGEBASE*EXP+CJ+XX=>LN;
 EXIT ;
::BASE16  I43:   IF   AA < B3, -> I4;
::BASE16   CJ3 => CJ;
::BASE16   C3 => CONST;
::BASE16  -> EVAL;
::BASE16  I4:;
::BASE16   CJ4 => CJ;
::BASE16   C4 => CONST;
::BASE16  -> EVAL;
::BASE16  I2:;
::BASE16   CJ2 => CJ;
::BASE16   C2 => CONST;
::BASE16  -> EVAL;
OVERFL:   ENTER.TRAP(8,14);
END ;
@END
@TITLE MFN01.3(1,6)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
SIN(X)
@BOX 2.0
CODE FOR SIN
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC SIN( AA);
$RE32  XX,YY;
$IN32  I;
LITERAL /$RE32     C1   =             0.636619772367591  ;
LITERAL /$RE32     ONE   =             1.000000000000003  ;
LITERAL /$RE32     P7   =            -0.000000000644621  ;
LITERAL /$RE32     P6   =             0.000000056882033  ;
LITERAL /$RE32     P5   =            -0.000003598809117  ;
LITERAL /$RE32     P4   =             0.000160441168470  ;
LITERAL /$RE32     P3   =            -0.004681754131060  ;
LITERAL /$RE32     P2   =             0.079692626245618  ;
LITERAL /$RE32     P1   =            -0.645964097506219  ;
LITERAL /$RE32     P0   =             1.570796326794894  ;
 AA * C1 => XX  => I;
IF   XX < 0. THEN
   1 -> I;
FI ;
I  -: XX=>YY;
IF  I & %1 = 0, -> L1;
 YY -: ONE => YY;
L1:  YY*YY=>XX*P7+P6*XX+P5*XX+P4*XX+P3*XX+P2*XX+P1*XX+P0*YY=>XX;
IF  I & %2 = 0, -> L2;
 XX -: 0. => SIN;
EXIT ;
L2:  XX => SIN;
EXIT ;
END ;
@END
@TITLE MFN01.4(1,6)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
COS(X)
@BOX 2.0
CODE FOR COS
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC COS( AA);
$RE32  XX,YY;
$IN32  I;
LITERAL /$RE32     C1   =             0.636619772367591  ;
LITERAL /$RE32     ONE   =             1.000000000000003  ;
LITERAL /$RE32     P7   =            -0.000000000644621  ;
LITERAL /$RE32     P6   =             0.000000056882033  ;
LITERAL /$RE32     P5   =            -0.000003598809117  ;
LITERAL /$RE32     P4   =             0.000160441168470  ;
LITERAL /$RE32     P3   =            -0.004681754131060  ;
LITERAL /$RE32     P2   =             0.079692626245618  ;
LITERAL /$RE32     P1   =            -0.645964097506219  ;
LITERAL /$RE32     P0   =             1.570796326794894  ;
LITERAL /$RE32     PIBY2   =             1.570796326794894  ;
 AA + PIBY2 * C1 => AA  => I;
IF   AA < 0. THEN
   1 -> I;
FI ;
I  -: AA => YY;
IF  I & 1 /= 0 THEN
    YY -: ONE => YY;
FI ;
 YY*YY => XX*P7+P6*XX+P5*XX+P4*XX+P3*XX+P2
  *XX+P1*XX+P0*YY => YY;
IF  I & 2 = 0 THEN
    YY => COS;
   EXIT ;
ELSE ;
    YY -: 0. => COS;
   EXIT ;
FI ;
END ;
@END
@TITLE MFN01.5(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TAN
@BOX 2.0
TAN = SIN/COS
(NOT VERY EFFICIENT)
@BOX 3.0
END
@BOX 1.1
PROC TAN(X);
@BOX 2.1
SIN(X)/COS(X) => TAN :: MAY CAUSE EXPONENT OVERFLOW

@BOX 3.1
END
@END
@TITLE MFN01.6(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ASIN
@BOX 2.0
ASIN = ATAN(X/SQRT(1-X*X))
@BOX 3.0
END
@BOX 1.1
PROC ASIN(X);
$RE32 Y;
@BOX 2.1
IF X < 0.9999999999 AND X > 0.-0.9999999999 THEN
SQRT(X*X-:1.) => Y; :: NEEDS SENSIBLE ARGUMENT;
ATAN(X/Y) => ASIN;
ELSE;
X * PIBY2=>ASIN;
FI;
@BOX 3.1
END;
@END
@TITLE MFN01.7(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ACOS
@BOX 2.0
ACOS = PI/2 - ASIN
@BOX 3.0
END
@BOX 1.1
PROC ACOS(X);
@BOX 2.1
ASIN(X) -: PIBY2 => ACOS;
@BOX 3.1
END;
@END
@TITLE MFN01.8(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ATAN(X)
@BOX 2.0
CODE FOR ATAN
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC ATAN ( AA);
$RE32  T,ATX,TS,X;
LITERAL /$RE32     XX1   =             0.267949192431123  ;
LITERAL /$RE32     XX2   =             1.000000000000000  ;
LITERAL /$RE32     XX3   =             3.732050818744749  ;
LITERAL /$RE32     X1   =             1.732050807568864  ;
LITERAL /$RE32     X12   =             4.000000000000000  ;
LITERAL /$RE32     X2   =             0.577350269189615  ;
LITERAL /$RE32     X22   =             1.333333333333333  ;
LITERAL /$RE32     P7   =            -0.052086939040000  ;
LITERAL /$RE32     P6   =             0.075307149134800  ;
LITERAL /$RE32     P5   =            -0.090813432247050  ;
LITERAL /$RE32     P4   =             0.111107941840294  ;
LITERAL /$RE32     P3   =            -0.142857085548841  ;
LITERAL /$RE32     P2   =             0.199999999489675  ;
LITERAL /$RE32     P1   =            -0.333333333331600  ;
LITERAL /$RE32     P0   =             1.000000000000000  ;
LITERAL /$RE32     PB6   =             0.523598775598299  ;
LITERAL /$RE32     PB3   =             1.047197551196598  ;
LITERAL /$RE32     PB2   =             1.570796326794897  ;
LITERAL /$RE32     ONE   =             1.000000000000000  ;
IF   AA => X < 0. THEN
   0. -:> X;
FI ;
IF   X > XX2, -> IN34;
IF   X =< XX1, -> ST1;
 X + X1 /: X12 -: X1 => T;
 PB6 => ATX;
->ST;
ST1:    X=> T;
    0. => ATX;
ST:    T*T => TS;
 P7*TS+P6*TS+P5*TS+P4*TS+P3*TS+P2*TS+P1*TS+P0*T+ATX=>X;
IF   AA < 0 THEN
   0. -:> X;
FI ;
 X => ATAN;
EXIT ;
IN34:   IF   X =< XX3, -> IN2;
 X /: ONE -: 0. => T;
 PB2 => ATX;
-> ST;
IN2:    X + X2 /: X22 -: X2 => T;
 PB3 => ATX;
->ST;
END ;
@END
@TITLE MFN01.9(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SINH
@BOX 2.0
E^X - E^-X/2
(INACCURATE 1X1<1)
@BOX 3.0
END
@BOX 1.1
PROC SINH(X);
@BOX 2.1
EXP(X) - EXP(0.-X)/2. => SINH;
@BOX 3.1
END;
@END
@TITLE MFN01.10(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
COSH
@BOX 2.0
E^X + E^-X/2
@BOX 3.0
END
@BOX 1.1
PROC COSH(X);
@BOX 2.1
EXP(X) + EXP(0.-X) /2. => COSH;
@BOX 3.1
END;
@END
@TITLE MFN01.11(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TANH(X)
@BOX 2.0
CODE FOR TANH
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC TANH( AA);
$RE32  XX,XSQ;
LITERAL /$RE32     C1   =            18.368410284838496  ;
LITERAL /$RE32     C2   =             0.162870578986080  ;
LITERAL /$RE32     P7   =             0.003592128036572  ;
LITERAL /$RE32     P6   =            -0.001455834387051  ;
LITERAL /$RE32     P5   =            -0.008863235529902  ;
LITERAL /$RE32     P4   =             0.021869488536155  ;
LITERAL /$RE32     P3   =            -0.053968253968254  ;
LITERAL /$RE32     P2   =             0.133333333333333  ;
LITERAL /$RE32     P1   =            -0.333333333333333  ;
LITERAL /$RE32     P0   =             1.000000000000000  ;
LITERAL /$RE32     ONE   =             1.000000000000000  ;
LITERAL /$RE32     TWO   =             2.000000000000000  ;
IF   AA => XX < 0. THEN
   0. -:> XX;
FI ;
IF   XX >= C1,->UNITY;
IF   XX>= C2,->L2;
 XX*XX=>XSQ*P7+P6*XSQ+P5*XSQ+P4*XSQ
+P3*XSQ+P2*XSQ+P1*XSQ+P0*XX=>XX;
EXITE: IF  AA > 0. THEN
 XX => TANH;
EXIT ;
ELSE ;
 0. - XX => TANH;
EXIT ;
FI ;
UNITY:  ONE => XX;
->EXITE;
L2:  EXP(TWO*XX)+ONE /: TWO -: ONE => XX;
->EXITE;
END ;
@END
@TITLE MFN01.15(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SQRT(X)
@BOX 2.0
CODE FOR SQRT
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC SQRT( AA);
$RE32  XX,M;
$IN EXP1,EXP2;
 IF   AA < 0., ->FAIL;
 IF   AA = 0., ->DONE;
LITERAL /$RE32     P0   =             5.021278583999997  ;
LITERAL /$RE32     P1   =           -22.334752489999978  ;
LITERAL /$RE32     P2   =            53.224909100000097  ;
LITERAL /$RE32     P3   =           -56.923922359999998  ;
LITERAL /$RE32     P4   =            22.057560799999968  ;
::BASE16 LITERAL /$RE32     RBASE   =             4.000000000000000  ;
::BASE2 LITERAL /$RE32   RBASE   =   1.414213562373094   ;
LITERAL /$RE32     THREE   =             3.000000000000000  ;
LITERAL /$RE32     HALF   =             0.500000000000000  ;
R.EXP(AA) => EXP1/2 => EXP2;
R.MANT(AA) => M;
  P4*M+P3*M+P2*M+P1*M+P0=>XX*M*XX-:THREE
   *XX*HALF => XX*M*XX -:THREE*XX*HALF=>XX
   *M*XX -:THREE*XX*HALF=>XX*M*XX
   -:THREE*XX*HALF*M => XX;
FORM.R(EXP2,XX) => XX;
IF  EXP1 & %1 = 0 ,-> L1;
IF EXP1 > 0. THEN
 XX*RBASE => SQRT;
ELSE
   XX/RBASE => SQRT;
FI
EXIT ;
L1:  XX => SQRT;
EXIT ;
FAILDONE:;
IF   AA/=0.,->FAIL;
DONE:  0. => SQRT;
EXIT ;
FAIL: ENTER.TRAP(8,11);
END ;
@END
@TITLE MFN01.16(1,6)
@COL 1A-2S-3T-4R-5N-6F
@COL 7T-8R-9N
@COL 10R
@ROW 4-7
@ROW 8-10
@ROW 5-9
@FLOW 2-3NO-4-5-6
@FLOW 3YES-7NO-8-9-5
@FLOW 7YES-10-9
@BOX 1.0
RPOWER
@BOX 2.0
RPOWER (P1,P2)
@BOX 3.0
P1 = 0?
@BOX 4.0
RESULT =
EXP (P2*LN(P1))
@BOX 5.0
@BOX 6.0
EXIT
@BOX 7.0
P2 = 0?
@BOX 8.0
RESULT = 0
@BOX 9.0
@BOX 10.0
@BOX 1.1

@BOX 2.1
PROC RPOWER( P1, P2);
@BOX 3.1
IF   P1=0.,
@BOX 4.1
 EXP(LN(P1)*P2)=>RPOWER;
@BOX 6.1
EXIT
END
@BOX 7.1
IF   P2=0.,
@BOX 8.1
0.=>RPOWER;
@BOX 10.1
ENTER.TRAP(8,12);
@END
@TITLE MFN01.17(1,10)
@COL 8A
@COL 1S-2T-3R-5R
@COL 9T-10R-11C-14T-18T-15R-16F
@COL 17R
@ROW 3-9
@ROW 15-17
@FLOW 1-2NO-3-5-14-18NO-15-16
@FLOW 14YES-16
@FLOW 2YES-9NO-10-11
@FLOW 9YES-17-16
@FLOW 18YES-17
@BOX 1.0
IPOWER(R,I)
@BOX 2.0
I=0?
@BOX 3.0
NEGATE I IF NEGATIVE
@BOX 5.0
CALC R**I=>R
@BOX 8.0
IPOWER
@BOX 9.0
R=0?
@BOX 10.0
RESULT=1
@BOX 11.0
EXIT
@BOX 14.0
I INITIALLY > 0
@BOX 18.0
R=0?
@BOX 15.0
1/R
@BOX 16.0
EXIT
@BOX 17.0
ENTER TRAP(8,12)
 0^0 OR -VE I
@BOX 1.1
LIPOWER:
PROC IPOWER( R, I);
$RE32  RKEEP;
$IN32  COUNT,BN;
LITERAL /$RE32  ONE=           1.000000000000000 ;
@BOX 2.1
IF  I=0,
@BOX 3.1
IF  I > 0 THEN
1 => BN -:I<<- 1=>I
ELSE
-1-I<<- 1=>I;
0=>BN;
FI
@BOX 5.1
 R=>RKEEP;
IF  I=0,->B5;
B5.1:
IF  I->> 1=>I&1=0,->B5.2;
 RKEEP*R=>R;
B5.2:
IF  I<2,->B5;
 RKEEP*RKEEP=>RKEEP;
->B5.1;
B5:
@BOX 9.1
   IF   R=0.,
@BOX 10.1
 ONE => IPOWER;
@BOX 11.1
EXIT
@BOX 14.1
   IF  BN=1,
@BOX 18.1
IF   R=0.,
@BOX 15.1
 ONE/R => R;
@BOX 16.1
 R => IPOWER;
EXIT
END
@BOX 17.1
ENTER.TRAP(8,12);
@END
@TITLE MFN01.18(1,6)
@COL 9R-10R
@COL 1S-2T-3T-4T-5T-6T-7R-8F
@COL 11T-12R-13R
@COL 14R-15R
@ROW 3-11
@ROW 9-6
@ROW 7-13-14
@FLOW 1-2NO-3NO-4NO-5NO-6NO-7-8
@FLOW 2YES-11NO-12-14-15
@FLOW 11YES-14
@FLOW 3YES-9-10
@FLOW 4YES-8
@FLOW 5YES-9
@FLOW 6YES-13-14
@BOX 1.0
POWER(I,J)
IS**IS
@BOX 2.0
I=0?
@BOX 3.0
I=1?
@BOX 4.0
J=1?
@BOX 5.0
J=0?
@BOX 6.0
J<0?
@BOX 7.0
FORM I**J
@BOX 8.0
END
@BOX 11.0
J/=0?
@BOX 10.0
RETURN
@BOX 9.0
SET RESULT TO 1
@BOX 13.0
FAULT -VE EXPONENT
ENTERTRAP(8,12)
@BOX 12.0
FAULT 0**0
ENTERTRAP(8,12)
@BOX 14.0
SET RESULT TO 0
@BOX 15.0
RETURN
@BOX 1.1
LPOWER:;
PROC POWER(I,J);
$IN32 [1] CONTROL;
$IN32  IT,JT;
@BOX 2.1
I => IT;
IF  I=0,
@BOX 3.1
IF  I=1,
@BOX 4.1
IF  J=1,
@BOX 5.1
IF  J=0,
@BOX 6.1
IF  J<0,
@BOX 7.1
2 => JT;
1 => CONTROL[ 0];
WHILE [CONTROL[ 0]=1 ]
DO
IT *> IT;
IF JT <<- 1 => JT >= J
THEN 0 => CONTROL[ 0];
FI;
OD;
IF  JT ->> 1 => JT /= J THEN
  1 => CONTROL[ 0];
WHILE [CONTROL[ 0]=1 ]
DO
;
  I *> IT;
  IF 1+>JT=J
THEN 0 => CONTROL[ 0];
FI;
OD;
FI ;
@BOX 8.1
IT => POWER;
END ;
@BOX 11.1
IF  J/=0,
@BOX 10.1
EXIT ;
@BOX 9.1
1. => POWER;
@BOX 13.1
ENTER.TRAP(8,12);
@BOX 12.1
ENTER.TRAP(8,12);
@BOX 14.1
0. => POWER;
@BOX 15.1
EXIT ;
@END


@TITLE MFN01.19(1,6)
@COL 2S-3R-4F
@FLOW 2-3-4
@BOX 2.0
PROC LOG(P1);
@BOX 3.0
EVAL LOG(P1)
@BOX 4.0
END
@BOX 2.1
PROC LOG( A);
LITERAL /$RE32  C=           0.434294481903247
@BOX 3.1
 LN(A)*C => LOG;
@BOX 4.1
EXIT ;
END ;
@END
@TITLE MFN01.20(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ATAN2(X1,X2)
@BOX 2.0
CODE FOR ATAN2
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC ATAN2( X1,  X2);
$IN32  FL;
$RE32  MULT,RES;
LITERAL /$RE32  PI=          3.141592653589793  ;
LITERAL /$RE32  PIBY2=          1.570796326794897  ;
LITERAL /$RE32  ONE=          1.000000000000000  ;
LITERAL /$RE32  M.ONE=         -1.000000000000000  ;
IF   X1 = 0 AND   X2 = 0 THEN
ENTERTRAP(8,13);
FI ;
IF   X1< 0. THEN
 M.ONE=>MULT;
   0. -:> X1;
ELSE ;
 ONE=>MULT;
FI ;
IF   X2 < 0. THEN
   0. -:> X2;
1=>FL;
ELSE ;
0=>FL;
FI ;
IF   X2=<X1 THEN
 ATAN( X2/X1)-:PIBY2=>RES;
ELSE ;
 ATAN( X1/X2)=>RES;
FI ;
IF  FL=1 THEN
 PI-RES*MULT=>ATAN2;
EXIT ;
ELSE ;
 RES *MULT=>ATAN2;
EXIT ;
FI ;
END ;
@END

