borchard m.-upgrading older fortran programs to current fortran-95 versions-computer program service...

Upload: nitroo17

Post on 03-Apr-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    1/21

    Upgrading older Fortran programs to

    current Fortran-95 versions

    Computer Program Service

    NEA Data Bank

    Study carried out by Michael Borchard, consultant.

    April 2001

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    2/21

    2

    Abstract

    This report describes the results of a study the Data Bank has undertaken to determine the difficulties

    encountered and the effort required to export codes written in Fortran-IV, Fortran-77, and platform

    specific implementations thereof to Fortran-95 compiler environments. The objective is to determine

    the survivability of not recently developed software across language and system evolution.

    The study is based on computer codes that had been released to the OECD/NEA and which are placedin the public domain. Samples from codes developed for diverse platforms were taken that appeared to

    be representative of typical problems normally encountered in such conversion efforts.

    First the different problems are classified, then the differences between the different standards are

    discussed, the computer / compiler dependencies are identified and finally specific solutions are

    proposed as well as tools that can help the transformation work.

    The study is not fully comprehensive of all possible problems encountered. These depend often on

    tricks used by programmers in old times to bypass machine and compiler limitations. One conclusion

    that can be drawn from this is that programs that were complying largely with standards of theprogramming languages at the time of their development have a high survival rate and can be used

    today without or with slight changes. Tricky programming style programs require considerable effort

    to be maintained also in the future.

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    3/21

    3

    Contents

    1 Classification of problems...........................................................................................................4

    2 Different standards .....................................................................................................................5

    3 Computer / compiler dependency .............................................................................................8

    3.1 General .................................................................................................................................8

    3.2 Compiler - dependency.........................................................................................................8

    3.3 Computer / processor dependency....................................................................................10

    4 References.................................................................................................................................14

    5 Appendix Non Standard Function Replacement....................................................................15

    6 Appendix - The Perils of Floating Point ...................................................................................16

    6.1.1 Binary Floating-Point...................................................................................................16

    6.1.2 Inexactness ..................................................................................................................16

    6.1.3 Insignificant Digits.......................................................................................................17

    6.1.4 Crazy Conversions .......................................................................................................17

    6.1.5 Too Many Digits..........................................................................................................18

    6.1.6 Too Much Precision .....................................................................................................18

    6.1.7 Safe Comparisons ........................................................................................................19

    6.1.8 Programming with the Perils ........................................................................................19

    6.2 IEEE Standard Floating-Point Formats................................................................................20

    6.2.1 Bibliography................................................................................................................20

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    4/21

    4

    1 Classification of problems

    This chapter contains the classification of problem sources, when upgrading to new language

    standards or new computer systems.

    Sources of problems persist in

    a) Differences in language definitions. The new Fortran language definitions are designed to keep upcompatibility to previous version(s) as far as possible. But Fortran-95 standard deleted some

    ancient features of FORTRAN-66 or FORTRAN IV, which were still available in FORTRAN-77

    and FORTRAN-90. The Fortran-2000 standard will go on removing old features. Most Fortran-

    95-compilers still accept these features as legal elements of the language, but they should be

    replaced by other up-to-date Fortran-elements, since their task is not always well defined.b) Differences in computer- or processor- architecture. These differences result in data representation

    mismatches, which lead to two sources of problems

    1) Different accuracy or alignment of data in memory. Accuracy and alignment problems can beresolved by using an appropriate compiler option.

    2) Mismatch of archived binary data, i.e. binary libraries or executable programs. Although

    binary libraries can be transformed if a precise format description exists, it will take muchtime and effort to do so. Binary libraries without precise format description cant be used

    anymore. Executable programs cannot be used on a different architecture and cannot be

    transformed.

    c) Differences in formatted output data. Some compilers read and write formatted input in anincompatible way to other compilers. This will especially happen for different formatted line ends.

    There exist two line end formats, which are incompatible. Thus it might be necessary to convert

    formatted data. The NEA Data Bank has tools to perform such conversion.d) Usage of compiler- or computer- specific intrinsic functions or subroutines. These functions or

    subroutines have to be replaced by up-to-date standard Fortran elements.

    e) Job-control-language statements in the source code. Job-control-language statements can beremoved from the source code. Sometimes the input data definition resides among these

    statements. It has to be preserved in a different file.The code-restructuring tool SPAG ( http://www.polyhedron.co.uk/pf/plusfort.html) is able to

    resolve some of the resulting problems automatically. And it generates a more readable source that is

    easier to translate to up-to-date Fortran.

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    5/21

    5

    2 Different standards

    During the development of FORTRAN its definition was subject to change. The ANSI-standard

    introduced FORTRAN 77 (

    [1]), which superseded FORTRAN IV / FORTRAN 66. Afterwards the

    FORTRAN-90 standard replaced FORTRAN 77. It is a superset of FORTRAN-77 and therefore any

    code that fulfils the requirements of ANSI-FORTRAN-77 is a syntactical correct FORTRAN-90 code.

    But some features of FORTRAN 77 were marked obsolescent. These features were kept only for

    compatibility of older programs and their use was no longer recommended. The Fortran-95-standard

    deleted these features and marked further features as obsolescent. But most Fortran-95 compilers

    recognise these obsolescent features as well as the deleted features, which are listed below:

    Variables used in DO-loops may no longer be REAL or DOUBLE PRECISION variables, butonly INTEGER-variables. The use of REAL and DOUBLE PRECISION variables could result ina computer dependent behaviour of the corresponding code. Thus this feature was removed.

    To upgrade a program using this feature such loop may be replaced by a DO WHILE-loop, e.g.:

    DO 100 R=1.0,17.3,0.1

    PRINT *,R100 CONTINUE

    could be replaced byR=1.0

    DO WHILE (R

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    6/21

    6

    300 PRINT *, END

    could be replaced byIF (J.EQ.1) THEN

    PRINT *, 100

    END IF

    IF (J.EQ.2) THEN

    PRINT *, 200END IF

    PRINT *, END

    In a replacement like this J must not be changed in the first IF-THEN-END IF structure. If a

    modification of J is unavoidable the code segment must be modified accordingly e.g.IF (J.EQ.1) THEN

    PRINT *, 100

    J=2

    ELSE IF (J.EQ.2) THEN

    PRINT *, 200

    J=J+1

    END IF

    PRINT *, J, END

    Another example is an ASSIGN combined with a DO-loop:104 DO 108 I=1,239

    ASSIGN 105 TO K

    GO TO 200

    105 RHO0=1./(D*12.56637062)

    ASSIGN 106 TO K

    GO TO 200

    106 RHO1(I)=3.*RHO0*D/(X1(I)**3)

    ASSIGN 107 TO K

    GO TO 200

    200 JJJ=A*10.

    GO TO K,(105,106,107)

    107 RHO2(I)=3.*RHO0*D/(X2(I)**3-X1(I)**3)

    108 E3(I)=E*(RHO3(I)**(2./3.))The last GOTO is an assigned GOTO supported by CDC FORTRAN. It checked K against the

    numbers in the brackets. The compiler printed an error message if K was different from all of

    these numbers. The correct replacement replaces the ASSIGN-statements as follows:104 DO 108 I=1,239

    JJJ=A*10.

    105 RHO0=1./(D*12.56637062)

    JJJ=A*10.

    106 RHO1(I)=3.*RHO0*D/(X1(I)**3)

    JJJ=A*10.

    107 RHO2(I)=3.*RHO0*D/(X2(I)**3-X1(I)**3)

    108 E3(I)=E*(RHO3(I)**(2./3.))

    This replacement is possible only with a look at the program flux. Another replacement could

    use a variable that holds the assigned value and an IF- or CASE-structure to GOTO theselected statement.

    The H-edit descriptor was deleted. The H(ollerith)-edit descriptor was used for text-constants inFORMAT-statements. It has to be replaced by the A-edit-descriptor and text following the H has

    to be quoted. The first character following the H-edit descriptor had a special meaning on some

    machines ( [2]). Usually this character formatted the output (e.g. a 1 meant new page beforeprinting the text). The SPAG source-code restructuring tool (

    http://www.polyhedron.co.uk/pf/plusfort.html) performs a replacement of H-edit descriptors

    automatically. An example of a replacement is listed below:

    WRITE (6,280)280 FORMAT (15H CROSS-SECTIONS)

    could be replaced byWRITE (6,280)

    280 FORMAT (15A, CROSS-SECTIONS)

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    7/21

    7

    A common way to read a title for the output was a labelled FORMAT-line with a dummy H-edit

    descriptor. A read with the label of this line led to a modification of this line. Thus a subsequentwrite could use this line to print the updated text. The following example demonstrates this

    behaviour: WRITE (6, 110)

    100 READ (7, 110)

    110 FORMAT (24HTO BE MODIFIED )WRITE (6, 110)

    This code segment would have produced the outputTO BE MODIFIED

    Modified text from input

    Provided that the next line of unit 7 is:Modified text from input

    This way of using Format specifications is illegal therefore the above code segment has to be

    modified. A correct replacement is stated below:CHARACTER TITLE*24

    TITLE=TO BE MODIFIED

    WRITE (6, 110) TITLE

    100 READ (7, 110) TITLE

    110 FORMAT (24A)

    WRITE (6, 110) TITLE

    Branching to an ENDIF-statement from outside the IF-THEN-ELSE structure is no longerallowed. Inserting a labelled CONTINUE-statement will solve such incompatibilities:

    IF (I .EQ. 0) GOTO 3IF (A .GE. 0.0) THEN

    WRITE (6, *) A

    ELSE

    WRITE (6, *) A**2

    3 ENDIF

    could be replaced byIF (I .EQ. 0) GOTO 3

    IF (A .GE. 0.0) THENWRITE (6, *) A

    ELSE

    WRITE (6, *) A**2

    ENDIF

    3 CONTINUE

    Remark:

    All tested compilers accepted the deleted features, except reading into an H-edit descriptor format line

    (stated above as illegal). Therefore no source-code modification was necessary due to different

    language definitions.

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    8/21

    8

    3 Computer / compiler dependency

    The usage of computer-, operating system- or compiler-specific functions will result in problems when

    using a program on a different computer, operating system or with a different compiler. A summary of

    such problems and their possible solutions is stated below. The problems arose while upgrading a

    couple of programs from FORTRAN IV / FORTRAN-66 / FORTRAN-77 to Fortran-95.

    3.1 General

    A general problem persisted in different character-sets that were used to write the programs. Some

    programs were not converted correctly from BCD (Binary Coded Decimal) to EBCDIC (ExtendedBinary Coded Decimal Interchange Code). In the current ASCII format these programs contain some

    strange characters. During the tests some packages not converted from BCD to EBCDIC, were found

    and modified accordingly (necessary replacements: % by (,

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    9/21

    9

    R=REAL(I+2)

    WRITE (2) R

    CLOSE (2)

    OPEN (UNIT=2, FORM=UNFORMATTED, STATUS=OLD)

    READ (2) DUMMY

    READ (2) R

    CLOSE (2)PRINT *, I was , INT (R)-2, and R is , R

    This code segment may printI was 2 and R is 4.0

    But if the REAL-variables like DUMMY and R differ in size from the INTEGER variable I it

    will print something else. For Lahey lf 95 youll obtain a different result if you use the dbl

    compiler option and for DEC-ALPHA f95 youll obtain a different result when using the

    compiler options r8 i4.

    Mismatch of the number of arguments for READ and the number of items in a formattedinput. Some compilers perform a special processing if the number of actual arguments in a

    READ-statement does not match the number of data available from the input stream.

    E.g. supposed the input

    1 2 3 45.0 6.0

    on unit 5 is read by the code segmentREAD (5, *) I, J, K

    READ (5, *) R, S, T

    The values ofI, J, K, R, S and T will usually be (and expected to be) I=1, J=2, K=3,

    R=5.0, S=6.0 and T undefined/unchanged. But for some compilers the code may stop with

    an error condition and for some others the values may be I=1, J=2, K=3, R=4.0, S=5.0

    and T=6.0

    Mismatch of status codes for IOSTAT (i/o-status). On successful completion of an i/o-operation the IOSTAT value will be 0. But in case of an error the IOSTAT-value is not well

    defined. Thus a program relying on a special error-value may not work with a different

    compiler/computer. The code could be modified to accept only a successful termination of ani/o-operation to resolve such problems. I.e. an IOSTAT value not equal 0 will result in

    program termination with the according error code.

    Non-standard edit-descriptors. Some compilers introduced edit descriptors for special purposes.E.g. IBM VS FORTRAN used the Q edit-descriptor to format extended precision (real) data. Such

    format descriptors have to be replaced by standard descriptors (e.g. Q D).

    DO loop index variables were sometimes used outside the range of the DO-loop. This is not

    recommended, although Fortran standard defines the according loop index value. Some ancient

    compilers disallowed this usage of a loop index by making the scope of the loop-index loop-local.

    Some codes tried to bypass this by assigning the loop index variable to a global variable of the

    same name. This does not work anymore. A legal replacement is stated below:DO 100 I=1,10

    I=I

    100 CONTINUE

    PRINT *, I

    This code segment solved the local definition problem of I, but it is illegal for up-to-date Fortran.

    The expected output of this code segment is 10. Deleting the line I=I would result in Fortran-

    95 conformance, but the output would be 11. Thus a correct replacement would be:DO 100 I=1,10

    IOUT=I

    100 CONTINUE

    PRINT *, IOUT

    Old Fortran-compilers did not provide character manipulation. Therefore some source codes usedINTEGER or REAL variables to store text. But it is not always possible to store the same amount

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    10/21

    10

    of characters in one INTEGER or REAL variable, because the length of those generic variables

    differs between different computers. The INTEGER and REAL variables holding character datacan be replaced by CHARACTER variables, since Fortran-95 standard provides as well as

    Fortran-77 standard character manipulation routines. An example is listed below:DIMENSION TEXT(4)

    DATA TEXT / INTEGRAL AVERAGE /

    TEXT is a REAL variable that is used to store text. The REAL format of Lahey lf95 uses 4 bytes tostore the REAL numbers. Thus an array of four REAL numbers (TEXT) provides 16 bytes storage

    space. But the desired text contains 24 characters and needs therefore 24 bytes storage space. A

    replacement for this code segment could be:CHARACTER TEXT*24

    DATA TEXT / INTEGRAL AVERAGE /

    Beside the general problem of not initialised variables, stated above, some not initialised variablesgive a hint to a typing error in the source code. E.g.:

    DO 11 I=1,K

    M1=4*K+3+I

    M2=M1+K

    M3=M2+KM4=M3+K

    M5=M4+K

    E=(T(M1)+T(M5)-4.*(T(M2)+T(M4))+6.*T(M6))/(12.*T(M5))

    WRITE(6,*) E

    11 CONTINUE

    In the formula for E M6 was undefined, but the variable M3 was not used in this formula. The

    examination of the calculation results and a discussion with the author resulted in the replacement

    ofM6 by M3. Thus the formula for E was modified to:E=(T(M1)+T(M5)-4.*(T(M2)+T(M4))+6.*T(M3))/(12.*T(M5))

    Date and time routines are a further source of incompatibilities, since no Fortran-standard before

    Fortran-90 defined such routines and their in- and output. Usually the compiler-/computer-specificdate and time routines were used to add time-stamps to the output. An easy way to resolve

    problems with non-standard date and time routines is the mapping of these routines to the standard

    DATE_AND_TIME function. An example is listed below:

    First the actual date (IDAY) and time (TIME) will be saved in two variables (IDATE and KLOCK)CALL IDAY (IDATE)

    CALL TIME (KLOCK)

    Now these values will be used in outputWRITE (4,*) TITLE

    WRITE (4,*) IDATE ,KLOCK

    To achieve Fortran-90/95 compatibility two subroutines have to be added to the sourceSUBROUTINE IDAY(IDATA)

    CHARACTER IDATA*8, TDUMMY*10, ZDUMMY*10

    CALL DATE_AND_TIME (IDATA, TDUMMY, ZDUMMY)

    RETURN

    END

    SUBROUTINE TIME(IDATA)

    CHARACTER IDATA*10, YDUMMY*8, ZDUMMY*10

    CALL DATE_AND_TIME (YDUMMY, IDATA, ZDUMMY)

    RETURN

    END

    3.3 Computer / processor dependency

    Some problems result not from compiler dependency of the source code but from computer or evenprocessor dependency of the source code. In context with real-number calculations and processor

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    11/21

    11

    dependency reference [5] contains a good explanation of problems. A list of computer / processor

    dependency problems is given below:

    OVERLAY PROGRAM inserted due to lack of memory must be converted to

    SUBROUTINE . By the use ofOVERLAY programs it was possible to load a necessary

    piece of program into the memory space of a no longer needed piece of program. Today

    OVERLAY is no longer useful and it is not an element of standard Fortran. Current computerssupport virtual memory and are equipped with random access memories big enough to hold all

    subroutines of a program at the same time. An example for the necessary replacement is listedbelow:

    NTLIB=10

    CALL OVERLAY(6LTERMOS,1,0)

    END

    OVERLAY(TERMOS,1,0)

    PROGRAM TERMOS

    COMMON /B100/ T(13,13,43),TT(1544)

    has to be replaced by

    NTLIB=10

    CALL TERMOS

    END

    SUBROUTINE TERMOS

    COMMON /B100/ T(13,13,43),TT(1544)

    Job Control Language (JCL) files contain usually statements to start the compiler, to prepare inputdata, to load and replace overlay modules and to execute the program. Most of these statements

    can be ignored or deleted safely. But the preparation of input data has to be checked carefully. The

    JCL-statement DD was often used to assign input and output files to Fortran-units. An example is

    listed below://GO.FT06F001 DD UNIT=L92,DISP=(NEW,PASS),LABEL=(1,SL),

    // VOLUME=(PRIVATE,SER=EN1109),DSNAME=ENEA1109

    // DCB=(,RECFM=F,BLKSIZE=133,TRTCH=ET,DEN=2)

    //GO.FT09F001 DD UNIT=L91,DISP=(NEW,PASS),LABEL=(1,SL),

    // VOLUME=(PRIVATE,SER=EN2068),DSNAME=ENEA2068

    //GO.SYSIN DD *

    50 2 2068 2 1 1 0 0 0 1 50 1

    0.14 0.31 0.42 0.55 0.60 0.69

    The first two DD-statements (five lines) define the output destinations for unit 6 and unit 9. All

    supplied hardware information can be ignored safely. The files fort.6 and fort.9 will be

    used for the output. On some systems unit 6 (=fort.6) is predefined as standard output. These

    systems will display all information sent to unit 6 on the screen. The last DD statement defines the

    standard input (usually unit 5). The two lines following this statement will be used as standard

    input data. Such DD-statements have to be translated. The two data lines (starting with 50)have to be copied in a file named fort.5 to be used as standard input in the example above. The

    other two DD statements can be ignored. Usually it is the easiest way to use Fortran unit files

    (fort.1 for Fortran unit 1, fort.2 for Fortran unit 2, fort.3 for Fortran unit 3, etc.), i.e. to

    copy the input files to the according unit files. Sometimes it may be better to use generic file

    names and to add OPEN statements to the source code. And sometimes the code has to bemodified more thoroughly, since some special features of JCL were used. An example is listed

    below://GO.FT06F001 DD SYSOUT=A,DCB=(RECFM=FBA,LRECL=133,BLKSIZE=3458)

    //GO.FT09F001 DD UNIT=TAPE9,VOL=SER=09,DISP=(OLD,PASS),

    // LABEL=(1,NL),

    // DCB=(RECFM=FB,LRECL=220,BLKSIZE=6600)

    //GO.FT09F002 DD VOL=REF=*.FT09F001,DISP=(OLD,PASS),// LABEL=(2,NL),

    // DCB=(RECFM=FB,LRECL=220,BLKSIZE=6600)

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    12/21

    12

    //GO.FT09F003 DD VOL=REF=*.FT09F001,DISP=(OLD,PASS),

    // LABEL=(3,NL),

    // DCB=(RECFM=FB,LRECL=220,BLKSIZE=6600)

    //GO.FT05F001 DD *

    INPUT DATA

    The first DD statement above defines the destination for output on unit 6. The next three DD

    statements concatenate three library files. The result is a data stream available on unit 9. An end-of-file mark is added at the end of each file of the stream, i.e. unit 9 contains three end-of-file

    marks. The last DD statement defines provided INPUT DATA on unit 5. The according program

    Pepin used the end-of-file marks to read the three different files from the unit 9 stream. For actualfiles the end-of-file mark does not exist anymore, but the end of file is the physical end of the file

    on the storage medium (usually a disk). Thus no file will contain more than one end of file.

    Therefore the Pepin source code had to be modified that it reads three different library files from

    three different Fortran unit streams. A short segment of the corresponding source code is listed

    below:397 READ(IB1,554,END=4)

    DO 396 I=1,M

    396 READ(IB1,556)

    GO TO 3974 DO 15 I=1,M

    8 READ(IB1,96)

    DO 22 I=1,M

    22 READ(IB1,555)

    7 READ(IB1,96)

    This code segment reads from unit IB1 until the end condition on line 397 is fulfilled, i.e. the

    end-of-file mark has been reached. In expectation of the next file being available on unit IB1 it

    continues reading from unit IB1 on line 8 afterwards. This code segment had to be modified that

    it reads from two different units/files (IB1, IB2):397 READ(IB1,554,END=4)

    DO 396 I=1,M

    396 READ(IB1,556)

    GO TO 397

    4 DO 15 I=1,M

    8 READ(IB2,96)

    DO 22 I=1,M

    22 READ(IB2,555)

    7 READ(IB2,96)

    Prerequisites to the length of integer and real values may lead to problems. THERMOS-OTA useddummy REAL variables to ignore some binary integer values while reading a binary library. This

    works only if REAL and INTEGER-variables are equal in size. The resulting error-message was

    an end-of-file error while reading. But a code not reading until the end-of-file may just produce adifferent result. To resolve such problems either change the variable type or use a compiler option

    that equalises sizes of REAL and INTEGER variables. This error is difficult to find, because the

    structure of the binary data file has to be determined from other parts of the source code.

    The REAL-format is system-dependent as well as all other data formats. A result of this differencemay be a mismatch in the computation results between two systems (

    [5]). If a program assumes

    for an INTEGER-value 16bit format and a cyclic increment (0, 1, 2,, 65534, 65535, 0, 1) a 32bitINTEGER-format on a different computer may result in a completely destroyed program flux.

    Such a problem did not arise during the program tests. To avoid such effects most compilers

    provide an option to select default data-representation-format. Usually these compiler options will

    solve problems resulting from machine dependent data formats. E.g. Lahey lf95 supports default

    double precision through the dbl option, DEC-ALPHA f95 supports default double precisionthrough the r8 option.

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    13/21

    13

    COMMON Block size mismatches may give a hint to alignment or variable size problems. E.g.Pepin (NEA1339 used the following common blocks in three routines:PROGRAM MAIN

    REAL*8 XNS

    ..

    COMMON/C1/XNS(650),XN0(650),XND(650,59)

    ..END

    SUBROUTINE A

    REAL*8 XNS

    ..

    COMMON/C1/XNS(650)

    ..

    END

    SUBROUTINE B

    ..

    COMMON/C1/EBM(650),EGM(650),SX(650),XND(650,59)

    ..

    END

    The usage of/C1/ in SUBROUTINE B assumed that REAL variables are half size ofREAL*8/DOUBLE PRECISION variables. But for some compilers this does not apply. To

    correct the arising output error SUBROUTINE B had to be modified. No data was transmitted

    through /C1/XNS(650) resp. /C1/EBM(650), EGM(650) therefore the modified version

    looks like:SUBROUTINE B

    REAL*8 EBM

    ..

    COMMON/C1/EBM(650), SX(650),XND(650,59)

    DIMENSION EGM(650)

    ..

    END

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    14/21

    14

    4 References

    [1] http://www.isi.edu/~iko/pl/hw3_fortran.html by In-Young Ko

    [2] Enrico Sartori NEA Data Bank

    [3] News group: comp.lang.fortran

    [4] http://www.fortran.com/FAQ by Keith Bierman

    [5] The Perils of Floating Point

    http://www.lahey.com/float.htm by Bruce M. Bush

    FORTRAN VERSION 5 MANUAL CDC OPERATING SYSTEM NEA Data Bank

    UNIVAC 1100 FORTRAN V Programmer Reference NEA Data Bank IBM VS FORTRAN Language Reference NEA Data Bank

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    15/21

    15

    5 Appendix Non Standard Function Replacement

    The compiler extensions that had to be replaced during the tests are listed below. The recommended

    replacement of the corresponding routine is a possible solution for error causing compiler extensions.

    Name Purpose Recommended replacementABNORMAL Relates to user functions, specifies their

    behaviour; UNIVAC FORTRAN V

    Remove

    DEFINE Used to define statement functions; UNIVACFORTRAN V

    Remove the keyword DEFINE notthe function definition

    DTIME Time routine Map to DATE_AND_TIME

    DUMP / PDUMP /CDUMP / CPDUMP /

    SDUMP

    Dumps a segment of memory; IBM VS

    FORTRAN

    Remove

    DVCHK Divide check exception test; one parameter getsthe result; IBM VS FORTRAN, UNIVACFORTRAN V

    Depends; usually it can beremoved; use compiler option toselect behaviour on division by

    zero

    ERRSET Set up routine for special error treatment; couldbe used to select user defined error subroutines;IBM VS FORTRAN

    Depends; usually it can beremoved; compiler option mayselect special error treatment

    ERRSAV / ERRSTR Routines to save and modify error behaviour in a

    variable; IBM VS FORTRAN

    Remove

    ERRTRA Error trace back routine; IBM VS FORTRAN Remove; use compiler option

    EXIT Terminate the execution STOP

    GOTO m,(m1,m2,..) Assigned GOTO. m was checked against m1,

    m2, etc. and could only have a value of theseparameters.

    Replace by GOTO m if no standard

    conformance is desired; otherwiserefer to chap. 2 (ASSIGN)

    IDAY Current date as CHARACTER*8 Map to DATE_AND_TIME

    INSTAT Status of last i/o statement; UNIVAC

    FORTRAN V

    Replace by IOSTAT-parameter of

    OPEN/READ/WRITEINTCTR Unknown, set probably system parameters Remove

    KILL Unknown

    OVERFL Processor register status check (overflow); IBM

    VS FORTRAN, UNIVAC FORTRAN V

    Depends; usually it can be

    removed; use compiler option toselect overflow behaviour

    PUNCH Output to a punchcard printer Replace by WRITE

    RANF Generate random numbers; probably between 0.0and 1.0

    Map to RANDOM_NUMBER

    SECOND Retrieve the number of CPU seconds used so far Map to CPU_TIME

    SETADR Direct access to storage media; first parameter is

    the unit number, second parameter is the address;UNIVAC FORTRAN V

    Use direct access for the according

    unit number

    SLITE Set status lights of the old computers; UNIVACFORTRAN V

    Remove or transform to a statusvariable

    SLITET Get status of the status lights; UNIVACFORTRAN V

    Remove or transform to a statusvariable

    SSWTCH Get status of an external computer switch;

    UNIVAC FORTRAN V

    Remove or transform to an input

    statement

    TIME Current time of day as CHARACTER*10 Map to DATE_AND_TIME

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    16/21

    16

    6 Appendix - The Perils of Floating Point

    by Bruce M. Bush

    Copyright (c) 1996 Lahey Computer Systems, Inc. Permission to copy is granted with

    acknowledgement of the source.

    Many great engineering and scientific advances of recent decades would not have been possiblewithout the floating-point capabilities of digital computers. Still, some results of floating-pointcalculations look pretty strange, even to people with years of mathematical experience. I will attempt toexplain the causes of some of these strange results and give some suggestions where appropriate.

    Floating-point representations and arithmetic are inexact, but I dont believe that is particularlytroublesome to most programmers. Many input values are measurements, which are inherentlyinexact, so the question about the output values isnt whether there is error, but how much error shouldbe expected. However, when you can compute a more accurate result in your head than yourcomputer can with its floating-point, you start to get suspicious.

    I have programmed my examples in FORTRAN for a couple of reasons:1. More floating-point calculations are performed in FORTRAN than any other computer language.2. I work for a company, Lahey Computer Systems, that develops and sells FORTRAN languagesystems.

    6.1.1 Binary Floating-Point

    At the heart of many strange results is one fundamental: floating-point on computers is usually base 2,whereas the external representation is base 10. We expect that 1/3 will not be exactly representable,but it seems intuitive that .01 would be. Not so! .01 in IEEE single-precision format is exactly10737418/1073741824 or approximately 0.009999999776482582. You might not even notice thisdifference until you see a bit of code like the following:

    REAL X

    DATA X /.01/

    IF ( X * 100.d0 .NE. 1.0 ) THEN

    PRINT *, Many systems print this surprising result.

    ELSE

    PRINT *, And some may print this.

    ENDIF

    Base-10 floating-point implementations dont have this anomaly. However, base-10 floating-pointimplementations are rare because base-2 (binary) arithmetic is so much faster on digital computers.

    6.1.2 Inexactness

    Floating-point arithmetic on digital computers is inherently inexact. The 24 bits (including the hiddenbit) of mantissa in a 32-bit floating-point number represent approximately 7 significant decimal digits.Unlike the real number system, which is continuous, a floating-point system has gaps between eachnumber. If a number is not exactly representable, then it must be approximated by one of the nearestrepresentable values.

    Because the same number of bits are used to represent all normalized numbers, the smaller theexponent, the greater the density of representable numbers. For example, there are approximately8,388,607 single-precision numbers between 1.0 and 2.0, while there are only about 8191 between1023.0 and 1024.0.

    On any computer, mathematically equivalent expressions can produce different values using floating-point arithmetic. In the following example, Z and Z1 will typically have different values because (1/Y) or1/7 is not exactly representable in binary floating-point:

    REAL X, Y, Y1, Z, Z1

    DATA X/77777/, Y/7/

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    17/21

    17

    Y1 = 1 / Y

    Z = X / Y

    Z1 = X * Y1

    IF (Z .NE. Z1) PRINT *, Not equal!

    END

    6.1.3 Insignificant Digits

    The following code example illustrates the phenomenon of meaningless digits that could seem to besignificant:

    REAL A, Y

    DATA Y /1000.2/ ! About 7 digits of precision in Y

    A = Y - 1000.0 ! About 3 significant digits in result

    PRINT *, A ! Prints 0.200012

    END

    A single-precision (REAL) entity can represent a maximum of about 7 decimal digits of precision, sothe subtraction above represents (1000.200 - 1000.000). The result, therefore, can only representabout 3 decimal digits. The program, however, will happily print out "0.200012". Because 1000.2 is not

    exactly representable in binary floating-point and 1000.0 is, the result A is a little larger than 0.2. Thecomputer doesnt know that the digits beyond ".200" have no meaning.

    Perhaps someday the computer will keep track of the number of bits in a result that are trulysignificant. For now, it is still the responsibility of the programmer. If you stay aware of the number ofdecimal digits represented by a data type, approximating the number of significant digits is a straight-forward, but perhaps time-consuming, task. Give the most attention to:

    1. subtractions of numbers that are nearly equal,2. additions of numbers whose magnitudes are nearly equal, but whose signs are opposite, and3. additions and subtractions of numbers that differ greatly in magnitude.

    6.1.4 Crazy ConversionsConversions to integer can unmask inaccuracies in a floating-point number, as is demonstrated by thenext example. The closest single-precision floating-point number to 21.33 is slightly less than 21.33, sowhen it is multiplied by 100., the result Y is slightly less than 2133.0. If you print Y in a typical floating-point format, rounding causes it to be displayed as 2133.00. However, if you assign Y to an integer I,no rounding is done, and the number is truncated to 2132.

    REAL X, Y

    INTEGER I

    X = 21.33 ! Slightly less than 21.33

    Y = X * 100. ! Slightly less than 2133.0

    I = Y ! Truncates to 2132

    PRINT *, Y, I ! Prints "2133.00 2132"

    END

    The following program prints "1.66661000251770" when compiled with Laheys LF90:

    DOUBLE PRECISION D

    REAL X

    X = 1.66661 ! Assign to single precision

    D = X ! Convert to double precision

    PRINT *, D

    END

    You ask, "Why do you extend the single-precision number with the seemingly random 000251770?"Well, the number isnt extended with random values; the computers floating-point does the conversionby padding with zeros in the binary representation. So D is exactly equal to X, but when it is printed outto 15 decimal digits, the inexactness shows up. This is also another example of insignificant digits.Remember that assigning a single-precision number to a double-precision number doesnt increasethe number of significant digits.

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    18/21

    18

    6.1.5 Too Many Digits

    You may decide to check the previous program example by printing out both D and X in the sameformat, like this:

    30 FORMAT (X, 2G25.15)

    PRINT 30, X, DIn some FORTRAN implementations, both numbers print out the same. You may walk away satisfied,but you are actually being misled by low-order digits in the display of the single-precision number. InLahey FORTRAN the numbers are printed out as:

    1.66661000000000 1.66661000251770

    The reason for this is fairly simple: the formatted-I/O conversion routines know that the absolutemaximum decimal digits that have any significance when printing a single-precision entity is 9. Therest of the field is filled with the current "precision-fill" character, which is "0" by default. The precision-fill character can be changed to any ASCII character, e.g., asterisk or blank. Changing the precision-fillcharacter to "*" emphasizes the insignificance of the low-order digits:

    1.66661000****** 1.66661000251770

    6.1.6 Too Much Precision

    The IEEE single-precision format has 24 bits of mantissa, 8 bits of exponent, and a sign bit. Theinternal floating-point registers in Intel microprocessors such as the Pentium have 64 bits of mantissa,15 bits of exponent and a sign bit. This allows intermediate calculations to be performed with muchless loss of precision than many other implementations. The down side of this is that, depending uponhow intermediate values are kept in registers, calculations that look the same can give differentresults.

    In the following example, a compiler could generate code that calculates A/B, stores the intermediateresult into a single-precision temporary, calculates X/Y, performs a reversed subtract of the temporary,then stores the result. Z will not be zero, because precision will be lost in storing into a single-precision

    temporary. If the generated code keeps the intermediate result in registers, no precision will be lost,and Z will be zero.

    REAL A, B, X, Y, Z

    DATA A/10./, B/3./, X/10./, Y/3./

    Z = (A/B) - (X/Y)

    PRINT *, Z ! Could be zero or not.

    END

    The next example illustrates a variation on the previous example. A compiler can still generate codethat keeps the intermediate result C in a register, which means that Z will be zero. If precision is lost bystoring A/B into C, then Z will be nonzero.

    REAL A, B, C, X, Y, ZDATA A/10./, B/3./, X/10./, Y/3./

    C = A/B

    Z = C - (X/Y)

    PRINT *, Z ! Could be zero or not.

    END

    The slight variation of adding the statement label 100 foils the optimization of keeping C in a register,so Z will probably be nonzero with almost any compiler.

    REAL A, B, C, X, Y, Z

    DATA A/10./, B/3./, X/10./, Y/3./

    C = A/B

    100 Z = C - (X/Y)

    PRINT *, Z

    IF ( ... ) GO TO 100

    END

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    19/21

    19

    6.1.7 Safe Comparisons

    Different computers use different numbers of bits to store floating-point numbers. Even when the sameIEEE formats are used for storing numbers, differences in calculations can occur because of the sizeof intermediate registers. To increase portability and to ensure consistent results, I recommend againstcomparing for exact equality of real numbers in FORTRAN. A better technique is to compare the

    absolute value of the difference of two numbers with an appropriate epsilon to get relations likeapproximately equal, definitely greater than, etc.Example:

    REAL EPSILON, X, A, B

    PARAMETER (EPSILON = .000001)

    DATA A/13.9/, B/.000005/

    X = (A * B) / B

    IF (ABS(X - A) .LE. (ABS(X)*EPSILON)) THEN

    PRINT *, X is approximately equal to A

    ENDIF

    IF ((X - A) .GT. (ABS(X)*EPSILON)) THEN

    PRINT *, X is definitely greater than A

    ENDIFIF ((A - X) .GT. (ABS(X)*EPSILON)) THEN

    PRINT *, X is definitely less than A

    ENDIF

    END

    Multiplying the epsilon by one of the comparands adjusts the comparison to the range of the numbers,allowing a single epsilon to be used for many, or perhaps all compares. For the most predictableresults, use an epsilon half as large and multiply it by the sum of the comparands, as in the followingexample:

    REAL EPSILON, X, A, B

    PARAMETER (EPSILON = .0000005) ! Smaller epsilon

    DATA A/13.9/, B/.000005/

    X = (A * B) / BIF (ABS(X - A) .LE. (ABS(X+A)*EPSILON)) THEN

    PRINT *, X is approximately equal to A

    ENDIF

    Even comparisons of greater-than, less-than-or-equal-to, etc., can produce unexpected results,because a floating-point computation can produce a value that is not mathematically possible. In thefollowing example X is always mathematically greater than J, so X/J should always be greater than1.0. For large values of J, however, the addition of delta is not representable by X, because of limitedmantissa size.

    REAL X, DELTA

    DATA DELTA/.001/

    DO 10 J = 1, 100 000

    X = J + DELTA ! Make X bigger than JCALL SUB (X) ! Force X out of register

    IF ( X/J .LE. 1.0 ) THEN ! X/J always > 1 ?

    PRINT *, Error !

    STOP

    END IF

    10 CONTINUE

    END

    SUBROUTINE SUB (X)

    END

    6.1.8 Programming with the Perils

    There are no easy answers. It is the nature of binary floating-point to behave the way I have described.In order to take advantage of the power of computer floating-point, you need to know its limitations andwork within them. Keeping the following things in mind when programming floating-point arithmetic

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    20/21

    20

    should help a lot:

    1. Only about 7 decimal digits are representable in single-precision IEEE format, and about 16 indouble-precision IEEE format.2. Every time numbers are transferred from external decimal to internal binary or vice-versa, precisioncan be lost.3. Always use safe comparisons.

    4. Beware of additions and subtractions that can quickly erode the true significance in a result. Thecomputer doesnt know what bits are truely significant. 5. Conversions between data types can betricky. Conversions to double-precision dont increase the number of truely significant bits.Conversions to integer always truncate toward zero, even if the floating-point number is printed as alarger integer.6. Dont expect identical results from two different floating-point implementations.

    I hope that I have given you a little more awareness of what is happening in the internals of floating-point arithmetic, and that some of the strange results you have seen make a little more sense.

    While some of the "perils" can be avoided, many just need to be understood and accepted.

    6.2 IEEE Standard Floating-Point Formats

    The Institute of Electrical and Electronics Engineers, Inc. (IEEE) has defined standards for floating-point representations and computational results (IEEE Std 754-1985). This section is an overview ofthe IEEE standard for representing floating-point numbers. The data contained herein helps explainsome of the details in the rest of the article, but is not required for understanding the basic concepts.

    Most binary floating-point numbers can be represented as 1.ffffff x 2^n, where the 1 is the integer bit,the fs are the fractional bits, and the n is the exponent. The combination of the integer bit and thefractional bits is called the mantissa (or significand). Because most numbers can have their exponentadjusted so that there is a 1 in the integer bit (a process called normalizing), the 1 does not need to bestored, effectively allowing for an extra bit of precision. This bit is called a hidden bit. Numbers arerepresented as sign-magnitude, so that a negative number has the same mantissa as a positivenumber of the same magnitude, but with a sign bit of 1. A constant, called a bias, is added to theexponent so that all exponents are positive.

    The value 0.0, represented by a zero exponent and zero mantissa, can have a negative sign. Negativezeros have some subtle properties that will not be evident in most programs. A zero exponent with anonzero mantissa is a "denormal." A denormal is a number whose magnitude is too small to berepresented with an integer bit of 1 and can have as few as one significant bit.

    Exponent fields of all ones (largest exponent) represent special numeric results. A mantissa of zerorepresents infinity (positive or negative); a nonzero mantissa represents a NAN (not-a-number). NANs,which occur as a result of invalid numeric operations, are not discussed further in this article.

    The IEEE Standard defines 32-bit and 64-bit floating-point representations. The 32-bit (single-precision) format is, from high-order to low-order, a sign bit, an 8-bit exponent with a bias of 127, and

    23 bits of mantissa. The 64-bit (double-precision) format is, a sign bit, an 11-bit exponent with a bias of1023, and 52 bits of mantissa. With the hidden bit, normalized numbers have an effective precision of24 and 53 bits, respectively.

    Single-precision format31, 30-23, 22-0S, Exponent, Significand

    Double-precision format63, 62-52, 51-0S, Exponent, Significand

    6.2.1 Bibliography

    American National Standards Institute (1978), "American National Standard, Programming LanguageFORTRAN", ANSI X3.9-1978, ISO 1539-1980 (E).

  • 7/29/2019 Borchard M.-upgrading Older Fortran Programs to Current Fortran-95 Versions-Computer Program Service (2001)

    21/21

    21

    IEEE Computer Society (1985), "IEEE Standard for Binary Floating-Point Arithmetic", IEEE Std 754-1985.

    Return to Lahey home page