Link to home
Start Free TrialLog in
Avatar of kphillips1
kphillips1Flag for United States of America

asked on

convert fortran real integer into an I8.8 integer

I am using fortran and in my program I am reading a .CSV file which cuts off leading and trailing zeros. I need to turn the number with 2 decimal places into an I8.8 integer?
Avatar of r-k
r-k

Can you please explain a bit more. What is an I8.8 integer?
Also, by "number with 2 decimal places", provide an example. Do you mean a number wityh 2 digits (e.g. 37) or do you mean a number with a fractional component, like 37.02 ?
  I don't quite follow your description. Presumably you have a disc file with a large amount of text, containing numbers separated by commas, thusly:
1234.5678,666,1,0,55
   Why should this format "cut off leading and trailing zeros"? Is your programme reading such files, or producing them?
   Using fortran, you could read such data using the free format option, thus:
      READ(IN,*) ARRAY
where ARRAY is indeed an array, of some size or other. If ARRAY is a floating-point type variable, then all numbers, integer or not, will be suitable for input. The main problem is, how many numbers are to be read in? Each line of input has the same count of numbers, or, some count that is knowable? Or, is perhaps the first number the count of numbers to follow? In this (useful and flexible case) case,
      READ (IN,*) N,(A(I),I = 1,N)
   would do the trick.
   What do you mean by I8.8? That is not a valid format code. Do you mean F8.8? Or what? If something has decimal places, it is not an integer. If you wish, you could rescale the numbers: read them into ARRAY as floating-point (with any fractional parts acceptable, then transfer the numbers to an integer array, thus:
      IARRAY = ARRAY*100
   or, if N were known to have been read,
      IARRAY(1:N) = ARRAY(1:N)*100

   Amusingly enough, I have been confronting .csv data, and the following code segment might help. Following an EATINT is EATREAL, as follows:

      LOGICAL FUNCTION EATREAL(V)      !This is even worse.[than EATINT]
Chews into the likes of 666, -666.666, and 666.666E666 (=666.666*10**666)
Completes with the value in V, success as the result, and L1 and L2 advanced.
Concocted by R.N.McLwean (whom God preserve) May XXMM.
       REAL*8 V,X,POW,TENS      !Maximum precision for all this fun.
       INTEGER*2 D,DD,P            !Digit counting and such.
       LOGICAL ADIGIT,XNEG,PNEG      !Things noticed along the way.
       REAL*8 TEN(0:8)            !A small table, only.
       DATA TEN/1,10,100,1000,10000,100000,1000000,10000000,100000000/      !Whee!
       CHARACTER*30 BURP      !In case of trace.
       INTEGER*2 I Am            !Self-identification.
        CALL $SUBIN("EatReal",I Am)      !Hello there.
        ADIGIT = .FALSE.      !No digits seen.
        PNEG = .FALSE.            !No negative exponent.
        XNEG = .FALSE.            !No negative number.
        DD = 0                  !No decimal digits.
        P = 0                  !No exponent.
        X = 0                  !No value.
        L2 = L1                  !The starting point.
        IF (L2.GT.LA) GO TO 40      !Urk! Off the end even before I start.
Chew into the number. Admit a possible leading sign, then digits.
        IF (ACARD(L2:L2).EQ."+") GO TO 1      !Well, first consider
        IF (ACARD(L2:L2).NE."-") GO TO 2      !Possible signs.
        XNEG = .TRUE.                  !To be acted upon later.
    1   L2 = L2 + 1                  !Advance one.
    2   IF (L2 .GT. LA) GO TO 30      !Off the end?
        D = ICHAR(ACARD(L2:L2)) - ICHAR("0")      !Taste the candidate digit.
        IF (D < 0 .OR. 9 < D) GO TO 10      !Is it to my taste?
        X = X*10 + D            !Yes. Yum.
        ADIGIT = .TRUE.            !A digit has been seen.
        GO TO 1                  !More might well follow.
Consider any decimal digits, those following a .
   10   IF (ACARD(L2:L2).NE.".") GO TO 20      !Any sign?
   11   L2 = L2 + 1            !Yes. Advance one.
        IF (L2.GT.LA) GO TO 30      !Sudden end?
        D = ICHAR(ACARD(L2:L2)) - ICHAR("0")      !Taste the digit candidate.
        IF (D < 0 .OR. 9 < D) GO TO 20      !Suitable?
        X = X*10 + D            !Yes. Accept as before.
        DD = DD + 1            !But now, count the decimal digits.
        ADIGIT = .TRUE.            !There may have been none before the decimal point.
        GO TO 11            !Carry on.
Consider any exponent part, following an "E" or "D", etc..
   20   IF (INDEX("EeDd",ACARD(L2:L2)).LE.0) GO TO 30      !Any sign?
        L2 = L2 + 1            !Step past it.
        IF (L2.GT.LA) GO TO 30      !Sudden stop?
        IF (ACARD(L2:L2).EQ."+") GO TO 21      !A (redundant) plus sign?
        IF (ACARD(L2:L2).NE."-") GO TO 22      !A - sign to notice?
        PNEG = .TRUE.            !Yes. Noticed.
   21   L2 = L2 + 1            !Advance one.
        IF (L2.GT.LA) GO TO 30      !As ever, after every advance, fear the brink.
   22   D = ICHAR(ACARD(L2:L2)) - ICHAR("0")      !Check for a digit.
        IF (D < 0 .OR. 9 < D) GO TO 30      !It is one?
        P = P*10 + D            !Yes. Build up the power part.
        GO TO 21            !And look some more.
Combine the components into one number then correct the power of ten.
   30   IF (XNEG) X = -X      !Correct the sign of the number.
        IF (PNEG) P = -P      !Correct the sign of any exponent.
        P = P - DD                !Now adjust the power of ten for decimal digits.
        IF (P .EQ. 0) GO TO 40      !No net fiddle! Yay!
        D = ABS(P)            !Oh well. Some power is required.
        POW = TEN(MOD(D,8))      !Gnash the bothersome low-order bits in one go.
        D = D/8                  !Now for the higher-order bits beyond the scope of my table.
        IF (D.LE.0) GO TO 32      !Are there any worthy of my regard?
        TENS = TEN(8)              !Yes! Prepare to acknowledge them.
   31   IF (MOD(D,2) .EQ. 1) POW = POW*TENS      !Bite this bit?
        D = D/2                  !So much for that level.
        IF (D .EQ. 0) GO TO 32      !Are we there yet?
        TENS = TENS*TENS      !No. Crank up another level,
        GO TO 31             !And keep trying.
   32   IF (P .GT. 0) THEN      !Because 0.1 = Binary .0001100110011001100110011001100....
          X = X*POW            !It is not represented in base two.
         ELSE                  !So *10 etc. is accurate,
          X = X/POW            !As is /10, etc.
        END IF                  !But *0.1 is inaccurate.
Complete the action.
   40   V = X                  !The result at last.
        IF (TRACE%EATREAL) THEN      !Are we under inspection?
          WRITE (BURP(3:),*) X      !Alright, reveal what was found.
          BURP(1:2) = "v="      !Squeeze in a prefix.
          CALL SHOWPLACE(BURP)      !Let the world know.
        END IF                  !So much for worries.
        IF (ADIGIT) THEN      !Something worked: advance the scan.
          L1 = L2            !Here is where I stopped looking.
          IF (L1.LE.LA) THEN      !Off the end?
            L2 = L1 + 1            !No. Co-ordinate fingers in case of a non-blank.
            IF (ACARD(L1:L1).EQ." ") CALL PASSSPACE      !Only if it is a blank.
          END IF            !Righto, the next non-blank is fingered.
        END IF                  !And L2 is one beyond it if L1 is not off the end.
        EATREAL = ADIGIT      !Report how we feel.
        CALL $SUBOUT("EatReal")      !I am done.
       RETURN                  !So farewell.
      END FUNCTION EATREAL      !Note that the number read is the parameter, NOT the result.

   This prog. is part of a larger collection of routines for the speedy scanning of vast input files. A record of input is read into character variable ACARD, whose last non-blank position is fingered by LA. The scan proceeds from L1, initially set to finger the first non-blank character in ACARD. Each invocation of EATREAL further advances L1 (should a number be read), leaving L1 fingering the next non-blank after the number. This would usually be a comma, and the loop invoking EATREAL invokes a PASSBY(",") to see if it should try for another number.
Avatar of kphillips1

ASKER

The .CSV file displays a 2 decilmal number 2.5 instead of 2.50. I need to convert that into 000250 or if the number is 1623.88 into 00162388.
ASKER CERTIFIED SOLUTION
Avatar of r-k
r-k

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial