borchard m.-upgrading older fortran programs to current fortran-95 versions-computer program service...
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