SUBROUTINE DOIT2 C C PURPOSE: EXECUTES COMMANDS RELATED TO STANDARD TRIGONOMETRIC FUNCTIONS, C ASSIGNED INTERNAL CODE #'S -99 TO -82. C C DESCRIPTION OF VARIABLES: C ANGLES -COMMON BYTE FLAG DETERMINING ANGULAR UNITS; SET TO 0=RADIANS C SET TO -VE=GRADS, SET TO +VE=DECIMAL DEGREES C CMND -COMMON BYTE ARRAY CONTAINING INTERNAL CODE # OF COMMAND C TO EXECUTE. C DTEMP -DOUBLE PRECISION TEMPORARY STORAGE C C SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIRED: C C PUSH--PUSHES STACK ELEMENTS C POP--POPS STACK ELEMENTS C DECDEG(X)--CONVERTS NUMBER CODED AS DD.MMSSSS TO DECIMAL DEGREES C DDMMSS(X)--CONVERTS DECIMAL DEGREES TO DD.MMSSSS CODE C C SORENSON 2/81 C COMMON/FLAGS/STATE,ERROR,STKLFT,NEST,ANGLES,DIGITS,RADIX,FLAG(4) BYTE FLAG,STATE,ERROR,STKLFT,NEST,ANGLES,DIGITS,RADIX COMMON/COMAND/LENGTH,CMND(40) BYTE CMND COMMON/STACK/X,Y,Z,T,XLST DOUBLE PRECISION X,Y,Z,T,XLST C C LOCAL VARIABLES C DOUBLE PRECISION DTEMP,RADDEG,DEGRAD,RADGRD,GRDRAD C C ARITHMETIC FUNCTION STATEMENTS FOR CONVERTING DEGREES OR GRADS TO C RADIANS AND BACK AGAIN...MOST COMPUTATIONS DONE IN RADIANS C DEGRAD(X)=X*0.0174532925199433D0 RADDEG(X)=X*57.2957795130823D0 GRDRAD(X)=X*.0157079632679490D0 RADGRD(X)=X*63.6619772367581D0 C C ALL CODES BUT "RAD","DEG", AND "GRD" SAVE CURRENT X IN LAST X REGISTER C ENABLE STACK LIFT ON NEXT ENTRY FOR ALL INSTRUCTIONS (STKLFT=1) C "GO TO" DIRECTS EXECUTION TO APPROPRIATE CODE C I=CMND(1)+100 IF(I.GT.18)GO TO 8 IF(I.LT.4)GO TO 4 XLST=X 4 STKLFT=1 GOTO(10,20,30,40,40,40,70,70,90,100,100,110,110,120,130,140, 1150,160),I C C CALLER MADE A MISTAKE, COMMAND NOT HANDLED HERE; RETURN C WITH ERROR -2 UNRECOGNIZED COMMAND C 8 ERROR=-2 RETURN C***** HANDLE COMMANDS HERE C C SET ANGLES TO "DEGREES" MODE C 10 ANGLES=1 RETURN C C SET ANGLES TO "RADIANS" MODE C 20 ANGLES=0 RETURN C C SET ANGLES TO "GRADS" MODE C 30 ANGLES=-1 RETURN C C COMMON ENTRY POINT FOR TRIG FUNCTIONS, CONVERT ANGLE TO RADIANS, C THEN GO TO APPROPRIATE FUNCTION CALL. C 40 IF(ANGLES)41,44,43 41 X=GRDRAD(X) GO TO 44 43 X=DEGRAD(X) 44 X=DMOD(X,6.2831853071795865D0) GO TO (45,50,60),I-3 45 X=DCOS(X) RETURN C C COMPUTE SINE -- REPLACE X C 50 X=DSIN(X) RETURN C C COMPUTE TANGENT -- REPLACE X C 60 X=DSIN(X)/DCOS(X) RETURN C C COMPUTE INVERSE TRIG FUNCTIONS -- REPLACE X , THEN BRANCH TO CONVERT C TO USER SELECTED ANGULAR MEASURE C 70 IF(DABS(X).GT.1.D0)GO TO 98 X=DSQRT((1.D0-X**2)/X**2) C C BRANCH HERE FOR ARCCOSINE C IF(I.EQ.7)GO TO 90 C C MUST BE ARCSINE C IF(X.NE.0.D0)GO TO 89 X=1.5707963267948966D0 GO TO 95 89 X=1.D0/X 90 X=DATAN(X) 95 IF(ANGLES)96,99,97 96 X=RADGRD(X) GO TO 99 97 X=RADDEG(X) GO TO 99 98 ERROR=-24 99 RETURN C C CONVERT DECIMAL DEGREES TO DD.MMSSSS FORMAT C 100 X=DDMMSS(X) RETURN C C ADD X AND Y CODED AS DD.MMSSSS -- PUSH STACK DOWN C 110 DTEMP=DECDEG(X) Y=DTEMP+DECDEG(Y) CALL POP X=DDMMSS(X) RETURN C C CONVERT DEGREES TO RADIANS -- REPLACE X C 120 X=DEGRAD(X) RETURN C C CONVERT RADIANS TO DEGREES -- REPLACE X C 130 X=RADDEG(X) RETURN C C CONVERT NUMBER IN DD.MMSSS CODE TO DECIMAL DEGREES C 140 X=DECDEG(X) RETURN C C CONVERT RECTANGULAR COORDINATES IN X AND Y TO POLAR COORDINATES C WITH ANGLE IN Y AND MAGNITUDE IN X C 150 X=DSQRT(X**2+Y**2) Y=DATAN(Y/XLST) IF(ANGLES)154,157,156 154 Y=RADGRD(Y) GO TO 157 156 Y=RADDEG(Y) 157 RETURN C C CONVERT POLAR COORDINATES TO RECTANGULAR COORDINATES C 160 IF(ANGLES)161,164,163 161 Y=GRDRAD(Y) GO TO 164 163 Y=DEGRAD(Y) 164 X=XLST*DCOS(Y) Y=XLST*DSIN(Y) RETURN END C***** FUNCTION SUBPROGRAMS REQUIRED FOR TRIG FUNCTIONS FUNCTION DECDEG(X) C C PURPOSE: CONVERTS X FROM CODED FORM DD.MMSSS TO DECIMAL DEGREES C DOUBLE PRECISION DECDEG,X,DDTEMP DDTEMP=DMOD(X,1.D0)*1.D2 IMIN=IDINT(DDTEMP) DECDEG=(DMOD(DDTEMP,1.D0)*1.6666666666666667D0+DBLE(FLOAT(IMIN))) 1*1.6666666666666667D-2+DBLE(AINT(SNGL(X))) RETURN END FUNCTION DDMMSS(X) C C PURPOSE: CONVERTS X IN DECIMAL DEGREES FORM TO DD.MMSSSS CODE C DOUBLE PRECISION DDMMSS,X,DDTEMP DDTEMP=DMOD(X,1.D0)*6.D1 IMIN=IDINT(DDTEMP) DDTEMP=DMOD(DDTEMP,1.D0)*6.D1 DDMMSS=DBLE(AINT(SNGL(X)))+DBLE(FLOAT(IMIN)*0.01)+DDTEMP*1.D-4 RETURN END