[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

convert fortran real integer into an I8.8 integer

Posted on 2005-04-13
7
Medium Priority
?
1,388 Views
Last Modified: 2013-11-08
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?
0
Comment
Question by:kphillips1
  • 2
  • 2
5 Comments
 
LVL 32

Expert Comment

by:r-k
ID: 13778904
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 ?
0
 
LVL 2

Expert Comment

by:RNMcLean
ID: 13778937
  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.
0
 

Author Comment

by:kphillips1
ID: 13785820
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.
0
 
LVL 32

Accepted Solution

by:
r-k earned 100 total points
ID: 13785876
<quote>
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.
</quote>

Are you saying that, given an input file with a line like:

2.5,1623.88

You want to write it out as:
00000250,00162388

(Note: I have 2 more zeroes with my 2.5 example than what you said above.)
0
 
LVL 2

Assisted Solution

by:RNMcLean
RNMcLean earned 100 total points
ID: 13787141
  It is still not clear whether your programme is to read, or to write the data.
   If the numbers are inside your programme, then you can multiply them by 100, round to an integer and write them out.
eg     V = 1623.88
        ...
        WRITE (6,*) INT(V*100)   !Function INT should round to the nearest integer.

   Alternatively,the furrytran FORMAT statement allows the use of the rather odd P specifier which for F-format will shift the decimal place (changing the value presented), as in
       WRITE (6,66) V
   66 FORMAT(2PF9.0)
   would give 162388. but that is still with a decimal point present, and there are no leading zeros.
   You could wtite the output to a character variable, and then fiddle the text to taste (removing the decimal point and adding the leading zeroes), or, if your furrytran supports it, you could use an extension of the I-format. I6 produces a six-digit field, with leading spaces, but I6.6 generates leading zeroes to supply at least six (the .6) digits. Thus,
       WRITE (6,66) INT(V*100)
   66 FORMAT(I6.6)
   Using integers means that you have to be sure that no number will go beyond the range of the integer.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
In this post we will learn different types of Android Layout and some basics of an Android App.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Progress
Suggested Courses
Course of the Month20 days, 2 hours left to enroll

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question