REAL FUNCTION FINP(BUF,NEXT,LENGTH) C C WRITTEN BY MIKE HIGGINS C CETUS CORP. C JUNE 15 1976, BETWEEN THE HOURS OF C 18:00 AND 23:00. C ****AND IT WORKED FIRST RUN!!!!****** C C FUNCTION TO CONVERT A STRING OF ALPHAS AND NUMERALS C INTO A FLOATING POINT REAL NUMBER. C C NUMBERS CAN BE IN ALMOST ANY FORM, FROM "12 " C (CONVERTS TO 12.0, NOTE LEFT JUSTIFICATION, CAN BE C RIGHT ALSO) TO "-12.34E-3" (CONVERTS TO 0.01234) C OR JUST ABOUT ANYWHERE INBETWEEN. DECIMAL POINTS ARE C ONLY NECC. WHERE THEY MAKE SENCE. "12 " OR "12. " C BOTH CONVERT TO 12.0, "12.3 " AND "123E-1 " C WILL BOTH CONVERT TO 12.30. C C CALLING CONVENTIONS: C C REAL=FINP(BYTARRAY,INTINDEX,INTMAXLENTH) C C REAL: REAL VARIABLE TO RETURN THE VALUE IN C C BYTARRAY: LOGICAL*1 ARRAY THAT CONTAINS THESTRING C TO BE CONVERTED. C C INTINDEX: AN INTEGER INDEX INTO THE LOGICAL*1 ARRAY THAT C POINTS TO THE FIRST CHARACTER TO BECONVERTED. C WHEN FINP RETURNS, THIS POINTER WILL BE C UPDATED TO POINT TO THE LAST CHARACTER C PROCESSED. IF THE NUMBER IN THE LOGICAL*1 C STRING WAS LEFT JUSTIFIED, INTINDEX WILL C POINT TO THE FIRST SPACE AFTER THE NUMBER. C IF THE NUMBER WAS RIGHT JUSTIFIED IN THE C ARRAY, INTINDEX WILL POINT TOA CHARACTER C AFTER THE LAST ONE, EVEN IF THIS MIGHT C CAUSE INTINDEX TO GO OUT OF BOUNDS IN C YOUR MAIN PROGRAM. C IF THE NUMBER IN THE LOGICAL*1 ARRAY WAS C TERMINATED BY A COMMA (","), INTINDEX C WILL BE RETURNNED POINTING TO THAT COMMA. C IF THERE WAS AN ILLEGAL CHARACTER (AND C CETUS HAS A LOT OF STRANGE CHARACTERS, YOU C MUST ADMIT) IN THE STRING, INTINDEX WILL C BE RETURNED POINTING TO THE OFFENDING CHARACTER. C C INTLENTH: THIS INTEGER VARIABLE OR VALUE TELLS C FINP THE MAXIMUM NUMBER OF CHARACTERS TO C SCAN WHEN CONVERTIN A NUMBER. THIS PARAMETER C IS ABSOLUTELY NECC. WHEN YOU ARE READING C RIGHT JUSTIFIED OR FIXED FORMAT DATA WITH FINP, C BUT WHEN YOU ARE READING NUMBERS THAT ARE C TERMINATED BY SPACES OR A COMMA, YOU CAN JUST C STICK ANY NUMBER LARGE ENOUGH IN INTLENTH C THAT WILL GUARATEE THAT THE DELIMITING CHARACTER C IS FOUND. C C INTEGER OUT COMMON /JOBLOG/OUT INTEGER PRT,DIV,LN,SQR,INR COMMON /MATHER/ PRT,DIV,LN,SQR,INR C C PRT A FLAG TO CONTROL PRINTING OF MATH ERRORS: C PRT = 0 MEANS PRINT ERROR MESSAGES ON OUTPUT C WHERE THEY OCCUR; C PRT # 0 MEANS PRINT TOTAL ERRORS ONLY, ON THE C JOBLOG. C C DIV THE NUMBER OF REAL-DIVIDE-BY-ZERO ERRORS C LN THE NUMBER OF LOG-OF-ZERO-OR-NEG-NUMBER ERRORS C SQR THE NUMBER OF SQUARE-ROOT-OF-NEG-NUMBER ERRORS C C INR THE NUMBER OF FLOATING CONVERSION ERRORS C LOGICAL*1 BUF(132),CHAR,SPC,ARR DATA SPC,ARR/" 40,"136/ NXT=NEXT LEN=NXT+LENGTH-1 FINP=0.0 IEXP=0.0 FLAG=1.0 IFLAG=1 C C IGNORE LEADING SPACES C 10 IF (BUF(NXT) .NE. " 40) GOTO 20 NXT=NXT+1 IF (NXT .LE. LEN) GOTO 10 RETURN C C SET A FLAG FOR NEGATIVE IF YOU SCAN A MINUS SIGN C 20 IF (BUF(NXT) .NE. " 55) GOTO 30 FLAG=-1.0 25 NXT=NXT+1 IF (NXT .GT. LEN) GOTO 998 30 CHAR=BUF(NXT) C C CHECK FOR LEGAL NUMERALS C IF ((CHAR .GT. " 71) .OR. (CHAR .LT. " 60)) GOTO 40 CHAR=CHAR-" 60 TEMR=CHAR FINP=FINP*10.0+TEMR GOTO 25 C C CHECK FOR A DECIMAL POINT C 40 IF (CHAR .NE. " 56) GOTO 60 SCALE=0.1 50 NXT=NXT+1 IF (NXT .GT. LEN) GOTO 998 CHAR=BUF(NXT) IF ((CHAR .GT. " 71) .OR . (CHAR .LT. " 60)) GOTO 60 CHAR=CHAR-" 60 TEMR=CHAR FINP=FINP+TEMR*SCALE SCALE=SCALE/10.0 GOTO 50 C C CHECK FOR ONE OF THE LEGAL TERMINATING CHARACTERS, A C SPACE OR A COMMA. C 60 IF ((CHAR .EQ. " 40) .OR. (CHAR .EQ. " 54) 1 .OR. (CHAR .EQ. 0)) GOTO 998 C C CHECK FOR AN "105 WHICH SIGNIFIES A BASE TEN EXPONENT FOLLOWS C IF (CHAR .NE. "105) GOTO 999 C C THERE IS AN EXPONENT. IF THERE WAS NO PRECEDING PART, C DEFAULT IT TO ONE SO THAT NUMBERS LIKE "E5" WIL C COME OUT CORRECTLY. ("E5" CONVERTS TO 100000, 'E-3' CONVERTS C TO .001) C IF (FINP .EQ. 0.0) FINP=1.0 C C CHECK FOR A NEGATIVE EXPONENT. C IF (NXT+1 .GT. LEN) GOTO 998 IF (BUF(NXT+1) .NE. " 55) GOTO 80 IFLAG=-1 NXT=NXT+1 C C INPUT AN INTEGER NUMBER FOR THE EXPONENT C 80 NXT=NXT+1 IF (NXT .GT. LEN) GOTO 998 CHAR=BUF(NXT) IF ((CHAR .LT. " 60) .OR. (CHAR .GT. " 71)) GOTO 90 CHAR=CHAR-" 60 ITEM=CHAR IEXP=IEXP*10+ITEM GOTO 80 90 IF ((CHAR .NE. " 40) .AND. (CHAR .NE. " 54) 1 .AND. (CHAR .NE. 0)) GOTO 999 C C NORMAL RETURN C 998 FINP=FLAG*FINP*(10.0**(IFLAG*IEXP)) NEXT=NXT IF (CHAR .EQ. 0) NEXT=NXT-1 RETURN 999 FINP=FLAG*FINP*(10.0**(IFLAG*IEXP)) IF (PRT .NE. 0) GOTO 430 WRITE(OUT,100)(BUF(I),I=NEXT,LEN) 100 FORMAT('0****CONVERSION ERROR****'/ 11X,130A1) WRITE(OUT,200)(SPC,I=NEXT,NXT),ARR 200 FORMAT(131A1) WRITE(OUT,300)FINP 300 FORMAT(' (MARK UNDER OFFENDING CHARACTER)'/ 1' THE VALUE RETURNED WILL BE ',G13.7/1X,25('*')/) 430 INR=INR+1 NEXT=NXT RETURN END