Fun

The most popular computer language is BASIC, which I explained earlier. Now you’ll learn a different computer language, called FORTRAN.

Most maxicomputers and minicomputers understand both BASIC and FORTRAN. Some ideas are easier to express in BASIC; others are easier in FORTRAN.

Most scientists and engineers on large computers use FORTRAN, not BASIC.

IBM invented the first version of FORTRAN in 1957. Then came improvements, called FORTRAN II, FORTRAN III, and FORTRAN IV. The next version was called FORTRAN 77 because it was invented in 1977. The newest version is called FORTRAN 90 because it was invented in 1990.

Some computers use FORTRAN 77 or FORTRAN 90. Others still use FORTRAN IV or a slightly souped-up version of it (called FORTRAN IV-EXTENDED or FORTRAN V or WATFOR or WATFIV or FORTRAN 10).

This chapter explains the popular FORTRAN features that work on practically all computers.

Simple programs

Here’s a FORTRAN program:

PRINT 10

10 FORMAT (1X,'CHIPMUNKS ARE CHUBBY')

PRINT 20

20 FORMAT (1X,'GOLDFISH GIGGLE')

PRINT 10

END

The top line says to print what’s in line 10, so the computer will print CHIPMUNKS ARE CHUBBY. The next line says to print what’s in line 20, so the computer will print GOLDFISH GIGGLE. The next line says to print what’s in line 10, so the computer will print CHIPMUNKS ARE CHUBBY again. Altogether, the program makes the computer print:

CHIPMUNKS ARE CHUBBY

GOLDFISH GIGGLE

CHIPMUNKS ARE CHUBBY

Notice:

Each program line is indented 6 spaces, so it begins in the 7^{th} position.

Each FORMAT begins with 1X.

Each string is enclosed in apostrophes.

You must number every line that’s referred to. For example, you must number the FORMAT lines, since the PRINT lines refer to them. You don’t have to number the PRINT lines.

The bottom line of every FORTRAN program must be END.

__Different versions__ On PDP computers, say TYPE instead of PRINT. On CDC computers using TS FORTRAN, replace each apostrophe by an asterisk. On IBM computers, put STOP above END, so the bottom two lines of your program are:

STOP

END

__How to type the program__ Ask the people in your computer center how to feed a FORTRAN program into the computer. On some computers, you must put an edit number in front of each line:

00100 PRINT 10

00110 10 FORMAT (1X,'CHIPMUNKS ARE CHUBBY')

00120 PRINT 20

00130 20 FORMAT (1X,'GOLDFISH GIGGLE')

00140 PRINT 10

00150 END

Some computers don’t require you to indent each line. To indent quickly on PDP computers, hold down the CONTROL key, while you type the letter I.

__Be brief__ Each line of your program must be brief: no more than 72 characters, including the spaces at the beginning of the line.

Carriage controls

The 1X at the beginning of each FORMAT is called the carriage control. It means: print the format normally.

For weirder printing, replace the 1X by ‘0’ or ‘1’ or ‘+’:

PRINT 10

10 FORMAT (1X,'NIFTY')

PRINT 20

20 FORMAT ('0','SAL')

END

In line 10, the 1X makes the computer print NIFTY normally. In line 20, the zero-in-apostrophes make the computer leave a blank line, then print SAL.

The computer will print:

NIFTY

SAL

Suppose you change the carriage control to ‘1’:

PRINT 10

10 FORMAT (1X,'NIFTY')

PRINT 20

20 FORMAT ('1','SAL')

END

If your terminal uses paper, the ‘1’ makes the computer print SAL on a new page. If your terminal uses a screen instead of paper, the ‘1’ makes the computer erase the screen before printing SAL.

Suppose you change the carriage control to ‘+’:

PRINT 10

10 FORMAT (1X,'NIFTY')

PRINT 20

20 FORMAT ('+','SAL')

END

If your terminal uses paper, the ‘+’ makes the computer print SAL in the same place as NIFTY, like this:

NSIAFLTY

If your terminal uses a screen instead, the computer will print NIFTY, but then the NIF will suddenly disappear, and you’ll see SALTY.

To print the symbol q , print 0 in the same place as -. To print the symbol ¹ , print = in the same place as /. To print q ¹ A, print 0=A in the same place as -/. If your terminal uses paper, this program prints q ¹ A:

PRINT 10

10 FORMAT (1X,'0=A')

PRINT 20

20 FORMAT ('+','-/')

END

__Different versions__ If you’re using a Hazeltine terminal or CDC TS FORTRAN, the carriage controls won’t work.

Fancy formats

In the format line, you can play fancy tricks.

__Multiple fields__ Examine this program:

PRINT 10

10 FORMAT (1X,'JOHN','NY')

END

The FORMAT consists of three fields: the first is the carriage control 1X, the second is `JOHN’, and the third is `NY’. The computer will print JOHN and NY on the same line:

JOHNNY

Another example:

10 FORMAT (1X,'EAT A',8X,'MEATBALL')

END

The computer will print EAT A, then 8 blank spaces, then MEATBALL:

EAT A MEATBALL

This program does the same thing:

PRINT 10

10 FORMAT (1X,'EAT A',T15,'MEATBALL')

END

It makes the computer print EAT A, then Tab over to the 15th position on the line, and print MEATBALL. When the computer tabs to the 15th position, it considers the carriage control to be the first "position"; the E in EAT is the first character the computer will print, and the computer considers it to be the second "position"; the A in EAT is the second character the computer will print, and the computer considers it to be the third "position"; the M in MEATBALL is the 14th character the computer will print, since the T15 says it is the 15th "position".

Here’s another program for meatball lovers:

PRINT 10

10 FORMAT (1X,'EAT A',1X,'MEATBALL')

The computer will print EAT A, then 1 blank space, then MEATBALL:

EAT A MEATBALL

If you say X instead of 1X, the computer will gripe.

__Multiple records__ This program quotes Julius Caesar:

PRINT 10

10 FORMAT (1X,'I CAME')

PRINT 20

20 FORMAT (1X,'I SAW')

PRINT 30

30 FORMAT (1X,'I CONQUERED')

END

The computer will print:

I CAME

I SAW

I CONQUERED

This program does the same thing:

PRINT 10

10 FORMAT (1X,'I CAME'/1X,'I SAW'/1X,'I CONQUERED')

END

Line 10 consists of 3 records: the first is 1X,`I CAME’; the second is 1X,`I SAW’; the third is 1X,`I CONQUERED’. Each record begins with a carriage control; the records are separated by slashes. The computer will print each record on a separate line.

Example:

PRINT 10

10 FORMAT (1X,'PLEASE'/1X,'NIBBLE'//1X,'MY'/////1X,'CHEESE')

END

Line 10 makes the computer print several lines. The first line will say PLEASE. The next line will say NIBBLE. The next line will be blank. The next line will say MY. The next 4 lines will be blank. The last line will say CHEESE. So altogether, the computer will print:

PLEASE

NIBBLE

MY

CHEESE

__Repeated formats__ The computer can feel very depressed:

PRINT 10

10 FORMAT (1X,'I FEEL ',3('DOWN'))

END

Line 10 is an abbreviation for this format:

1X,'I FEEL ','DOWN','DOWN','DOWN'

The computer will print:

I FEEL DOWNDOWNDOWN

Let’s burp and pray:

PRINT 10

10 FORMAT (1X,'JACK ',2('BURPS'/1X,'MARY '),'ALSO PRAYS')

END

Line 10 is an abbreviation for this format:

1X,'JACK ','BURPS'/1X,'MARY ','BURPS'/1X,'MARY ','ALSO PRAYS'

The computer will print:

JACK BURPS

MARY BURPS

MARY ALSO PRAYS

__Double apostrophe__ To make the computer print an apostrophe, use two apostrophes next to each other.

PRINT 10

10 FORMAT (1X,'MOMMY ISN"T HERE')

END

The computer will print:

MOMMY ISN'T HERE

Continuation

Some computers look at only the first 72 characters of each line of your program: if your line contains more than 72 characters, it won’t work.

If you want to type a long statement, type just the first 72 characters. On the line below, type the remaining characters, beginning in the 7th print position; and in the 6th print position type a 6:

PRINT 10

10 FORMAT (1X,'I LIKE ROSES IN MY TEA.'/1X,'THEY MAKE IT GLOW RED, LI

6KE HOT BLOOD.')

END

The computer will print:

I LIKE ROSES IN MY TEA.

THEY MAKE IT GLOW RED, LIKE HOT BLOOD.

A line that has a 6 in column 6 is called a continuation line, because it’s a continuation of the line above it.

(I suggest you put a 6 in column 6, or a * in column 6, or a $ in column 6. In fact, you can put *any character* in column 6, except a zero. Choose your favorite character; the computer doesn’t care.)

__Different versions__ On PDP computers, put the 6 immediately after a controlled I, instead of in column 6:

10 FORMAT (1X,'I LIKE ROSES IN MY TEA.'/1X,'THEY MAKE IT GLOW RED, LI

6KE HOT BLOOD.')

(I suggest you put a 6 after the controlled I. But you can put in *any non-zero digit*, instead of a 6.)

On CDC computers using TS FORTRAN, type a + instead of a 6, and put it immediately after the edit number, with no intervening spaces:

00120 10 FORMAT (1X,'I LIKE ROSES IN MY TEA.'/1X,'THEY MAKE IT GLOW RED, LI

00130+KE HOT BLOOD.')

GO TO

You can say GO TO:

10 PRINT 20

20 FORMAT (1X,'CAT')

PRINT 30

30 FORMAT (1X,'DOG')

GO TO 10

END

The top line says to print what’s in line 20, so the computer will print:

CAT

The next line says to print what’s in line 30, so the computer will print:

DOG

The next line makes the computer go back to line 10. The computer will print CAT again, then DOG again, then jump back to line 10 again.… The computer will try to print the words CAT and DOG again and again, forever.

STOP

The computer understands the word STOP:

PRINT 10

10 FORMAT (1X,'BUBBLE GUM')

PRINT 20

20 FORMAT (1X,'SHAKESPEARE')

STOP

PRINT 30

30 FORMAT (1X,'DADA')

END

The top line says to print what’s in line 10, so the computer will print BUBBLE GUM. The next line says to print what’s in line 20, so the computer will print SHAKESPEARE. The next line says STOP, so the computer will stop. It will never print DADA.

Math

FORTRAN handles math rather well.

Integers versus real numbers

FORTRAN distinguishes between integers and real numbers. Here’s how FORTRAN defines them.…

An integer contains no decimal point and no exponent.

__Integer__ __Not an integer__ __Comment__

-27 -27.0 An integer contains no decimal point.

50000 5E4 An integer contains no exponents.

A real number contains either a decimal point or the letter E.

__Real number__ __Not a real number__

-27.0 -27

2.35E8 235000000

5E4 50000

The largest permissible integer is different from the largest permissible real:

__Computer__ __Largest integer__ __Largest real__ __Tiniest real__

PDP-11 using Fortran IV 32767 1.7E38 2.9E-39

PDP-11 using Fortran IV-Plus 2147483647 1.7E38 2.9E-39

PDP-10 or Honeywell 34359738367 1.7E38 2.9E-39

IBM mainframe 2147483647 7.2E75 5.4E-79

CDC 281474976710655 2.5E322 3.1E-294

Integers are also called fixed-point numbers. Real numbers are called floating-point numbers.

Variables

In BASIC, X can stand for a number, such as 3.7. The same is true in FORTRAN. A variable can be a letter (such as X) or a letter-followed-by-a-combination-of-letters-and-digits (such as FUN4U2).

The variable must be short: no more than 6 characters. AVERAGE is too long: say AVERAG instead.

If the variable begins with I, J, K, L, M, or N, it stands for an integer. If it begins with some other letter, it stands for a real number.

Using integer variables

Here’s a simple example:

JUNKY=-47

PRINT 10, JUNKY

10 FORMAT (1X,I3)

END

Since JUNKY begins with J, it stands for an integer. The first line says JUNKY stands for the integer -47. The second line says to print JUNKY, using line 10. Line 10 explains how to print JUNKY. The I3 means: print it as an Integer having 3 characters. The computer will print:

-47

If you change the I3 to I4, the computer will print JUNKY as an Integer having 4 characters. To print a total of 4 characters, the computer will print a blank space in front of -47, like this:

-47

If you change to I5, the computer will print JUNKY as an Integer having 5 characters, by printing two blank spaces in front of -47:

-47

If you change to I2, the computer will try to print JUNKY as an integer having 2 characters. But it’s impossible to express -47 by using only 2 characters. The computer will obey the format and print 2 characters, but will make them asterisks:

**

Another example:

NUM=31.9

PRINT 10, NUM

10 FORMAT (1X,I4)

END

Since NUM begins with N, it stands for an integer. The program’s top line tries to make NUM stand for 31.9; but that’s impossible, since 31.9 isn’t an integer. The computer will omit the .9 and make NUM stand for the integer 31. The computer will print 31, using an I4 format:

31

Example:

JOE=-5.8

PRINT 10, JOE

10 FORMAT (1X,I4)

END

The computer will set JOE equal to the integer -5 and print it:

-5

Example:

JAIL=74

KRIMNL=829

PRINT 10, JAIL,KRIMNL

10 FORMAT (1X,I2,I3)

END

Since JAIL begins with J, and KRIMNL begins with K, they’re both integers. The computer will print JAIL and KRIMNL, using the format in line 10. The format says to print a 2-character integer, then a 3-character integer. The computer will print:

74829

If you change the format to (1X,I2,4X,I3), the computer will print a 2-character integer, then 4 blanks, then a 3-character integer:

74 829

If you change the format to —

10 FORMAT (1X,'JAIL NUMBER',1X,I2,1X,'CONTAINS CRIMINAL',1X,I3)

the computer will print JAIL NUMBER, then a blank, then a 2-character integer, then a blank, then CONTAINS CRIMINAL, then a blank, then a 3-character integer:

JAIL NUMBER 74 CONTAINS CRIMINAL 829

Example:

J=43

K=75

L=96

M=81

N=24

PRINT 10, J,K,L,M,N

10 FORMAT (1X,I2,I2,I2,I2,I2)

END

The computer will print 43, then 75, then 96, then 81, then 24:

4375968124

You can write that format more briefly:

10 FORMAT (1X,5I2)

If you change the format to (1X,5I3), the computer will print each integer as 3 characters — a blank followed by two digits:

43 75 96 81 24

If you change the format to (1X,I3), the computer will print only one integer per line:

43

75

96

81

24

If you change the format to (1X,2I3), the computer will print 2 integers per line:

43 75

96 81

24

If you change the format to (1X,’GOSH’,I3,1X,’SUPERB’,I3,1X,’JEEPERS’), the computer will print 2 integers per line:

GOSH 43 SUPERB 75 JEEPERS

GOSH 96 SUPERB 81 JEEPERS

GOSH 24 SUPERB

To be safe, use I14 format for integers. On most computers, I14 handles even the largest integers, and prints blank spaces between them.

Using real variables

The I format is only for integers. For real numbers, use F or G format instead.

__F format__ The F format is easy to understand:

RADIUS=-586.39

PRINT 10, RADIUS

10 FORMAT (1X,F7.2)

END

Since RADIUS doesn’t begin with I, J, K, L, M, or N, it stands for a real number. The first line says RADIUS stands for the real number -586.39. The second line says to print RADIUS, using the format in line 10. The F7.2 means: print it as a floating-point number having 7 characters, 2 of them after the decimal point. The computer will print:

-586.39

If you change the F7.2 to a different format, the following chart shows what happens; in the chart, each represents a blank space:

__Format__ __What the computer prints__ __Comment__

F8.2 -586.39 To print 8 characters instead of 7,

it prints a blank space at the beginning.

F8.3 -586.390 To print 3 characters after the decimal point instead of 2,

it prints a zero at the end.

F8.1 -586.4 To print 1 character after the decimal point instead of 2,

it rounds the .39 to 4.

F8.4 ******** To print 4 characters after the decimal point,

the computer would have to print -586.3900.

Since that requires more than 8 characters,

the computer complains by printing asterisks.

__G format__ To print a real number, the safest format is G14.6, because G14.6 can handle *any* real number well, even if the number is very large or very tiny.

G14.6 prints 14 characters altogether, 6 of which are significant digits. Here are examples of numbers printed in G14.6 format:

-0.283941E-29

0.293027

5.34523

39.4539

47802.3

986327.

0.288341E+24

Example:

PRUNES=17

PRINT 10, PRUNES

10 FORMAT (1X,G14.6)

END

Since PRUNES doesn’t begin with I, J, K, L, M, or N, it stands for a real number. When the computer encounters the first line of the program, it will set PRUNES equal to the real number 17.0. It will print:

17.0000

The program will run faster if you change the top line to this:

PRUNES=17.0

__E format__ For real numbers, the usual formats are F and G, but another option is E.

If you say E14.6 instead of G14.6, the computer will print an E in the answer. Here are examples:

__Using G14.6 format__ __Using E14.6 format__

-0.283941E-29 -0.283941E-29

0.293027 0.293027E+00

5.34523 0.534523E+01

39.4539 0.394539E+02

47802.3 0.478023E+05

986327. 0.986327E+06

0.288341E+24 0.288341E+24

The G14.6 format is easier for a human to read than E14.6. But most programmers are stupid, don’t know about G14.6, and use E14.6 instead.

__P format__ FORTRAN’s notation differs from BASIC.

If you ask the computer to print 288341000000000000000000.0 in FORTRAN by using G14.6 (or E14.6), the computer will normally print a 0 before the decimal point, like this: 0.288341E+24. In BASIC, the computer will print a non-zero digit before the decimal point, like this: 2.88341E+23.

If you’re writing a program in FORTRAN, but you prefer BASIC’s notation, ask for 1PG14.6 (or 1PE14.6). The 1P makes the computer imitate BASIC. But if a FORMAT contains 1PG, it must not contain F afterwards; this will print a wrong answer:

FORMAT (1X,1PG14.6,F8.2)

Here is P. The F afterwards prints a wrong answer!

Operations

For addition, subtraction, multiplication, and division, FORTRAN uses the same symbols as BASIC.

N=2*(3+1)

S=7.3+2.1

PRINT 10, N,S

10 FORMAT (1X,I14,G14.6)

END

Since N is 8, and S is 9.4, the computer will print:

8 9.40000

__Exponents__ For exponents, FORTRAN uses a double star:

J=7**2

P=.5**3

PRINT 10, J,P

10 FORMAT (1X,I14,G14.6)

END

Since J is 72 (which is 49), and P is .53 (which is .125), the computer will print:

49 0.125000

For negative exponents, you need parentheses. You must say 6.1**(-2), not 6.1**-2.

__What type of answer?__ When you combine integers, the answer’s an integer:

2+3 is 5

8-8 is 0

2*4 is 8

399/100 is 3 (not 3.99)

11/4 is 2 (not 2.75)

3/4 is 0 (not 0.75)

10**(-2) is 0 (not 0.01)

When you combine real numbers, the answer is real:

4.1+2.9 is 7.0 (not 7)

8.0-8.0 is 0.0 (not 0)

399.0/100.0 is 3.99

11.0/4.0 is 2.75

3.0/4.0 is .75

10.0**(-2.0) is .01

When you combine an integer with a real number, the answer is real:

3+2.0 is 5.0

399/100.0 is 3.99

11/4.0 is 2.75

3/4.0 is .75

10.0**(-2) is .01

Compare these:

7/10*10 is 0 (because 7/10 is 0)

7/10*10.0 is 0.0 (because 0*10.0 is 0.0)

7/10.0*10 is 7.0 (because 7/10.0 is .7)

Example:

JERK=20.0+30.9

PRINT 10, JERK

10 FORMAT (1X,I14)

END

Since JERK begins with J, it stands for an integer. Since 20.9+30.9 is 51.8, JERK stands for the integer 51. The computer will print:

51

Another example:

APPLE=37/10

PRINT 10, APPLE

10 FORMAT (1X,G14.6)

END

Since APPLE begins with A, it stands for a real number. Since 37/10 is 3, APPLE stands for the real number 3.0. The computer will print:

3.00000

__Crimes that slow down the computer cop__ If you commit one of these crimes, the computer will work slowly.…

Little crime: use a real number

Medium crime: mix reals with integers

Big crime: use a real exponent

For example, the computer handles 2.0+2.0 slower than 2+2, because 2.0+2.0 is a little crime.

The bigger the crime, the slower the computer works. For example, the computer handles 2.1+7 (which is a medium crime) slower than 2.1+7.0 (which is just a *little* crime). Likewise, X=0 (a medium crime) gets handled slower than X=0.0 (a little crime).

5.1**2.0 is a big crime, since its exponent (2.0) is real. The computer handles it slower than 5.1**2, which is just a medium crime.

5**3.1 is a gigantic crime, since it’s a medium crime and a big crime simultaneously. Because the crime’s so gigantic, some computers refuse to handle it. Say 5.0**3.1 instead.

Advice about variables

FORTRAN, like BASIC, distinguishes variables, constants, and expressions:

X is a variable

2.7 is not a variable; it’s a numeric constant

'LOVE' is not a variable; it’s a string constant

X+Y is not a variable; it’s an expression

In a PRINT statement, some computers allow only variables.…

allowed: PRINT 10, X

not allowed: PRINT 10, 2.7 instead, say X=2.7 and PRINT 10, X

not allowed: PRINT 10, 'LOVE' instead, say PRINT 10 and 10 FORMAT (1X,'LOVE')

not allowed: PRINT 10, X+Y instead, say Z=X+Y and PRINT 10, Z

Other computers are more generous and allow anything. Find out about yours.

To help other humans understand your program, use long variable names throughout your program. Say RADIUS, not R; say AREA, not A; say VOLUME, not V; say SUM, not S; say TOTAL, not T. Because FORTRAN’s variables are restricted to six characters, you might have to omit the last few syllables (*revolutions* becomes REVOLU) or the last few vowels (RVLTNS).

If you want a variable to be real, but its English name begins with I, J, K, L, M, or N, begin its FORTRAN name with an A (*mass* becomes AMAS; *length* becomes ALENGT or ALNGTH). If you want a variable to be an integer, but its English name doesn’t begin with I, J, K, L, M, or N, begin its FORTRAN name with an I (*population* becomes IPOPUL) or misspell it (*count* becomes KOUNT) or choose a synonym (instead of *position*, say *location*, which is LOCATN).

Pleasant I/O

You learned how to make the computer PRINT by using a FORMAT. Now you’ll learn about PRINT’s opposite (READ) and how to omit FORMATs altogether.

READ

The computer can READ.

PRINT 10

10 FORMAT (1X,'TYPE SOME DIGITS')

READ 20, N

20 FORMAT (I4)

PRINT 30, N

30 FORMAT (1X,I4)

END

When you run the program, here’s what happens.…

The top two lines make the computer print:

TYPE SOME DIGITS

The word READ makes the computer wait for you to type something; it’s like the BASIC word INPUT. The computer will wait for you to type the value of N, but line 20’s FORMAT makes the computer read just the first 4 characters. For example, if you type —

-75198622

the computer will read just the first 4 characters, which are -751; it will ignore the 98622; so N will be -751. Line 30’s FORMAT makes the computer print:

-751

Altogether, the run looks like this:

The computer says: TYPE SOME DIGITS

You say: -75198622

The computer replies: -751

__Hassles__ Line 30’s FORMAT contains a carriage control 1X, but line 20’s FORMAT omits the carriage control. Put a carriage control in formats that PRINT, but not in formats that READ.

On PDP computers, say ACCEPT instead of READ.

__Blank spaces__ If you input a blank space, the computer treats it as a zero.

For example, suppose you input:

-3 28219

Because of the I4 format, the computer will read just the first 4 characters, which are -3 2; the blank space between the 3 and the 2 is treated as a zero, so N will be -302.

Suppose you input:

57

Because of the I4 format, the computer will read the 5, the 7, and two blanks. Since the blanks are treated as zeros, N will be 5700.

Suppose you input:

9527

Because of the I4 format, the computer will read the three beginning blanks and the 9. Since the blanks are treated as zeros, N will be 0009, which is 9. Line 30 makes the computer print:

9

__Multiple variables__ Suppose you write a program containing these lines:

READ 20, L,M,N

20 FORMAT (I3,I4,2X,I2)

When you run that program, suppose you input:

58194138972824

The I3 format makes the first 3 characters (581) be L. The I4 format makes the next 4 characters (9413) be M. The 2X format makes the next 2 characters (89) be skipped over. The I2 format makes the next two characters (72) be N. The remaining characters (824) are ignored. So the line is split like this.…

Line you input: 58194138972824

Fields in the FORMAT statement: I3 I4 2XI2

Variables in the READ statement: L M N

Suppose you write a program containing these lines:

READ 20, J,K,L,M,N

20 FORMAT (2I3)

The format says to read two 3-character integers on each line. Suppose you input:

78345692

85431684

46185327

J will be 783, and K will be 456. L will be 854, and M will be 316. N will be 461.

__Real variables__ Here’s how to input a real number:

PRINT 10

10 FORMAT (1X,'TYPE SOME DIGITS')

READ 20, P

20 FORMAT (F6.2)

PRINT 30, P

30 FORMAT (1X,G14.6)

END

The F6.2 format means: read 6 characters; if they don’t contain the decimal point, insert it before the last 2 digits.

For example, suppose you input:

327514968

The computer reads the first 6 characters (327514). Since they don’t contain the decimal point, the computer inserts it before the last 2 digits, so P is 3275.14. Line 30 prints:

3275.14

Suppose you input:

7.5423967

The computer reads the first 6 characters (7.5423). Since they already contain the decimal point, P is 7.5423. Line 30 says to print that number by using 6 significant digits, so the computer prints:

7.54230

Suppose you input:

497E3

The computer reads 6 characters (497E3, followed by a blank). Since blanks are treated as zeros, the computer gets 497E30. Since 497E30 doesn’t contain the decimal point, the computer inserts it before the last 2 digits, so P is 4.97E30. Line 30 prints:

0.497000E+31

Omitting formats

Most computers let you omit numeric formats. This program works on most modern computers (such as computers having FORTRAN 77, PDP-20 computers, PDP-10 computers using FORTRAN 10, PDP-11 computers using FORTRAN IV-PLUS, CDC computers using FORTRAN IV-EXTENDED, and IBM computers using FORTRAN H-EXTENDED):

PRINT 10

10 FORMAT (1X,'TYPE TWO INTEGERS')

READ *, M,N

ISUM=M+N

PRINT *, ISUM

END

(On PDP computers, say TYPE instead of PRINT, and ACCEPT instead of READ.)

The word READ is followed by an asterisk, instead of a FORMAT number. The last PRINT is followed by an asterisk also. The asterisk makes the computer invent its own FORMAT. To make the program add 241 and 82976, input the numbers, separated by a comma:

241,82976

The computer will notice the comma’s location and automatically use an I3 format for 241, a 1X format to skip over the comma, and an I5 format for 82976. To print ISUM, the computer will use a safe format, such as I14 or I15.

By omitting formats, you gain two advantages:

1. You can write FORTRAN programs faster.

2. The person who inputs needn’t worry whether his spacing matches the format. The computer invents a format matching his input.

__Different versions__ On CDC computers using TS FORTRAN and on Honeywell computers, omit the asterisk after READ and PRINT:

PRINT 10

10 FORMAT (1X,'TYPE THE NUMBERS')

READ, M,N

ISUM=M+N

PRINT, ISUM

END

On PDP-10 computers using F40 FORTRAN, and on PDP-11 computers using regular FORTRAN IV, you need FORMATs, but omit the number in the I format:

TYPE 10

10 FORMAT (1X,'TYPE THE NUMBERS')

ACCEPT 20, M,N

20 FORMAT (1X,2I)

ISUM=M+N

TYPE 30, ISUM

30 FORMAT (1X,I)

END

__Real numbers__ You can use similar shortcuts for real numbers.

Logic

You learned how to say GO TO and STOP. Taking those concepts further, let’s see how to say IF and DO and give a *computed* GO TO.

IF

FORTRAN uses these clauses:

__Clause__ __Meaning__

IF (I .LT. 5) If I is Less Than 5

IF (I .GT. 5) If I is Greater Than 5

IF (I .LE. 5) If I is Less than or Equal to 5

IF (I .GE. 5) If I is Greater than or Equal to 5

IF (I .EQ. 5) If I is EQual to 5

IF (I .NE. 5) If I is Not Equal to 5

Notice that each relational operator (such as LT) must be enclosed in periods, and each condition (such as I .LT. 5) must be enclosed in parentheses.

By using those clauses, you can build statements:

__Statement__ __Meaning__

IF (I .LT. 5) J=3 If I is Less Than 5, let J=3

IF (I .LT. 5) GO TO 80 If I is Less Than 5, go to line 80

IF (I .LT. 5) STOP If I is Less Than 5, stop

IF (I .LT. 5) PRINT 10, J If I is Less Than 5, print J using line 10’s FORMAT

You can use the words AND and OR:

__Idea__ __How to say it in FORTRAN__

If I is 2 or 9 or 13 IF (I .EQ. 2 .OR. I .EQ. 9 .OR. I .EQ. 13)

If I is an integer from 1 to 8 IF (I .GE. 1 .AND. I .LE. 8)

If X<Y<Z IF (X .LT. Y .AND. Y .LT. Z)

If A is less than both B and C IF (A .LT. B .AND. A .LT. C)

If X negative or between 5 & 9 IF (X .LT. 0.0 .OR. X .GE. 5.0. .AND. X .LE. 9.0)

Take this test: cover the column that says "How to say it in FORTRAN". Try to translate each "Idea" into FORTRAN, then check your answers. If one of your answers is shorter than the correct answer, take the test again! For example, the following answer to the first idea is *wrong*:

IF (I .EQ. 2 .OR. 9 .OR. 13)

__END IF__ FORTRAN 77 lets you say "END IF".

For example, here’s how FORTRAN 77 lets you say, "If I is greater than 5, let J be 80 and let K be 90":

IF (I .GT. 5) THEN

J=80

K=90

END IF

Here’s how FORTRAN 77 lets you say, "If I is greater than 5, let J be 80 and let K be 90; but if I is *not* greater than 5, let J be 30 and let K be 50":

IF (I .GT. 5) THEN

J=80

K=90

ELSE

J=30

K=50

END IF

Here’s how FORTRAN 77 lets you say, "If I is greater than 5, let J be 80 and let K be 90; if I is *not* greater than 5, but I is greater than 2, let J be 81 and let K be 92; if I is not greater than 2, let J be 30 and let K be 50":

IF (I .GT. 5) THEN

J=80

K=90

ELSE IF (I .GT. 2) THEN

J=81

K=92

ELSE

J=30

K=50

END IF

Warning: to say "END IF", you must get FORTRAN 77. If you use FORTRAN IV instead, "END IF" doesn’t work. I recommend that you get FORTRAN 77.

__Three-way IF__ Here’s a different kind of IF statement:

IF (X) 20,50,90

It means:

If X is a negative number, go to line 20.

If X is zero, go to line 50.

If X is a positive number, go to line 90.

That kind of IF statement is called a three-way IF, or an arith__met__ic IF. (To pronounce "arith*met*ic", put the accent on *met*.) The other kind of IF is called a logical IF.

In your program, you can say:

GO TO (80,100,20,350), I

That means: go to either 80, 100, 20, or 350, depending on what I is. More specifically, it means:

Go to line 80, if I is 1.

Go to line 100, if I is 2.

Go to line 20, if I is 3.

Go to line 350, if I is 4.

Proceed to the line underneath, if I is a different integer.

That FORTRAN statement is called a computed GO TO.

DO

This program prints the square of every number from 80 to 95, and then prints GET LOST:

__BASIC__ __FORTRAN__

FOR I = 85 TO 100 DO 20 I=80,95

PRINT I ^ 2 J=I**2

PRINT 10, J

10 FORMAT (1X,I14)

NEXT 20 CONTINUE

PRINT "GET LOST" PRINT 30

30 FORMAT (1X,'GET LOST')

END

If you compare the BASIC with the FORTRAN, you’ll notice FORTRAN uses the word DO instead of FOR, uses a comma instead of TO, and uses CONTINUE instead of NEXT. The statement DO 20 I=5,9 means: DO every line up through line 20, repeatedly, as I goes from 5 to 9. In BASIC, programmers indent every line between FOR and NEXT; in FORTRAN, programmers indent every line between DO and CONTINUE. In BASIC, the indented lines are called a FOR...NEXT loop; in FORTRAN, they’re called a DO loop.

If you want the computer to print the square of every *fifth* number from 80 to 95, change the program’s top line:

__BASIC__ __FORTRAN__

FOR I = 80 TO 95 STEP 5 DO 20 I=80,95,5

__Restrictions__ In a DO statement, some computers allow only positive integer variables and constants:

__Not allowed__ __Why__ __Say this instead__

DO 10 X=1.0,5.0 reals are not allowed DO 10 I=1,5

DO 10 X=17.3,98.5 reals are not allowed DO 10 I=173,985

X=I/10.0

DO 10 I=0,5 0 is not positive DO 10 J=1,6

I=J-1

DO 10 I=-3,5 -3 is not positive DO 10 J=1,9

I=J-4

DO 10 I=100,7,-1 -1 is not positive DO 10 J=7,100

I=107-J

DO 10 I=5,J+K + is not allowed L=J+K

DO 10 I=5,L

Other computers are more generous and allow anything. Find out about yours.

In the middle of a DO loop, don’t change the value of the index. For example, if your DO loop begins with —

DO 10 I=1,100

don’t insert this line in the middle of your loop:

I=14

It will confuse the computer.

__Zero-trip DO loops__ If you say —

DO 10 I=1,N

the computer will do up through line 10, N times. For example, if N is 73, the computer will do up through line 10, 73 times. If N is 2, the computer will do up through line 10, twice. If N is 1, the computer will do up through line 10, once.

What happens if N is less than 1? The answer depends on which version of FORTRAN you’re using.

If you’re using FORTRAN 77, the computer will skip the loop, and proceed to the line below line 10. But if you’re using FORTRAN IV, the computer will do the loop once, as if N were 1.

FORTRAN 77 makes more sense; but alas, many computers still use FORTRAN IV.

A DO loop that FORTRAN 77 skips (because N is less than 1) is called a zero-trip DO loop, because the computer takes "zero trips through the loop" (instead of 1 trip or 2 trips or many trips).

Find out whether *your* computer’s version of FORTRAN resembles FORTRAN 77 and permits zero-trip DO loops.

Lists

To handle lists, use these tricks.…

Subscripts

Like BASIC, FORTRAN permits subscripts:

DIMENSION X(4)

X(1)=.21

X(2)=.3

X(3)=1.08

X(4)=5.0

SUM=X(1)+X(2)+X(3)+X(4)

PRINT 10, X,SUM

10 FORMAT (1X,G14.6)

END

The top line says X will be a list of 4 numbers, called X(1), X(2), X(3), and X(4). Since X doesn’t begin with I, J, K, L, M, or N, the 4 numbers will be real.

The PRINT statement makes the computer print the list and the SUM, like this:

0.210000

0.300000

1.08000

5.00000

6.59000

If you change the format to (1X,5G14.6), the computer will print all 5 numbers on the same line:

0.210000 0.300000 1.08000 5.00000 6.59000

You must say DIMENSION if your program uses subscripts, even if the subscripts are small. Say DIMENSION at the very top of the program. Make sure you say DIMENSION, not DIM or DIMENSIONS. The computer assumes all subscripts will be positive, so don’t say X(0). If a subscript is zero or negative or larger than the DIMENSION statement says, the computer might not notice your error, and will print wrong answers without warning you.

If your program begins like this —

DIMENSION A(6)

READ 10, A

the computer will begin by reading 6 real numbers, which will become A(1), A(2), A(3), A(4), A(5), and A(6).

__Double subscripts__ If you want T to be a table of numbers, and you want T to have 4 rows and 2 columns, begin your program by saying:

DIMENSION T(4,2)

To print T, say:

PRINT 10, T(1,1), T(1,2)

PRINT 10, T(2,1), T(2,2)

PRINT 10, T(3,1), T(3,2)

PRINT 10, T(4,1), T(4,2)

10 FORMAT (1X,2G14.6)

If you say —

PRINT 10, T

the computer will print the entire table T, but in an undesirable order: it will print T(1,1), T(2,1), T(3,1), and T(4,1), then T(1,2), T(2,2), T(3,2), and T(4,2). Similarly, "READ 5, T" makes the computer read T in an undesirable order.

Implied DO

This statement —

PRINT 10, X(3),X(4),X(5),X(6),X(7)

can be written more briefly, like this:

PRINT 10, (X(I), I=3,7)

It means: using line 10’s format, print the value of X(I), for I = 3 to 7. The construction (X(I), I=3,7) is called an implied DO loop. Notice the parenthesis at the beginning, the parenthesis at the end, and the commas.

Here are other examples of implied DO loops:

__Implied DO loop__ __Meaning__

(X(I), I=100,120,5) X(100),X(105),X(110),X(115),X(120)

(X(I),Y(I), I=3,7) X(3),Y(3), X(4),Y(4), X(5),Y(5), X(6),Y(6), X(7),Y(7)

__Calendar__ Here’s a calendar:

1 2 3 4 5 6 7

8 9 10 11 12 13 14

15 16 17 18 19 20 21

22 23 24 25 26 27 28

29 30 31

This program prints it:

PRINT 10, (I, I=1,31)

10 FORMAT (1X,I2,1X,I2,1X,I2,1X,I2,1X,I2,1X,I2,1X,I2)

END

The program’s top statement says to print every value of I, for I = 1 to 31. The FORMAT says to print 7 integers on each line, and separate the integers by spaces.

Since 1X followed by I2 is about the same as I3, you can write the FORMAT more briefly:

10 FORMAT (I3,I3,I3,I3,I3,I3,I3)

You can be even briefer:

10 FORMAT (7I3)

__Tables__ If T is a table having 3 rows and 5 columns, these lines will print it in the correct order:

PRINT 20, T(1,1), T(1,2), T(1,3), T(1,4), T(1,5)

PRINT 20, T(2,1), T(2,2), T(2,3), T(2,4), T(2,5)

PRINT 20, T(3,1), T(3,2), T(3,3), T(3,4), T(3,5)

20 FORMAT (1X,5G14.6)

This shortcut does the same thing:

PRINT 20, (T(1,J), J=1,5)

PRINT 20, (T(2,J), J=1,5)

PRINT 20, (T(3,J), J=1,5)

20 FORMAT (1X,5G14.6)

Here’s a shorter cut:

PRINT 20, ((T(I,J), J=1,5), I=1,3)

20 FORMAT (1X,5G14.6)

To read the table, say:

READ 10, ((T(I,J), J=1,5), I=1,3)

DATA

This program shows FORTRAN’s DATA statement, which differs from BASIC’s:

__Program__ __Meaning__

DATA X/8.7/, Y/1.4/, Z/9.0/ X is 8.7, Y is 1.4, and Z is 9.0.

X=100.6 X changes to 100.6

PRINT 10, X,Y,Z The computer will print:

10 FORMAT (1X,3G14.6) 100.600 1.40000 9.00000

END

In that DATA statement, you must write 9.0, not 9: the number must be real, since Z is real.

The DATA statement resembles these three statements —

X=8.7

Y=1.4

Z=9.0

but is faster.

Here’s another way to type the DATA statement:

DATA X,Y,Z/8.7,1.4,9.0/

It says X, Y, and Z are 8.7, 1.4, and 9.0 respectively.

Like the DIMENSION statement, the DATA statement belongs at the very top of the program. If you want both a DIMENSION statement and a DATA statement, put the DIMENSION statement first.

This DATA statement says A, B, C, D, and E are all 1.7, and X, Y, and Z are all 9.6:

DATA A,B,C,D,E,X,Y,Z/1.7,1.7,1.7,1.7,1.7,9.6,9.6,9.6/

Since the first 5 numbers are 1.7, and the next 3 numbers are 9.6, you can write more briefly:

DATA A,B,C,D,E,X,Y,Z/5*1.7,3*9.6/

__Subscripted DATA__ To make A be this list —

81.7

92.6

25.3

49.8

72.1

68.8

begin your program with these lines:

DIMENSION A(6)

DATA A/81.7,92.6,25.3,49.8,72.1,68.8/

To make T be this table —

8.4 9.7

5.1 6.8

2.5 7.2

6.3 9.8

begin your program with these lines:

DIMENSION T(4,2)

DATA T/8.4,5.1,2.5,6.3,9.7,6.8,7.2,9.8/

Notice you must list the entire first column, then the second.

String variables

This program works on most computers:

N='UP'

PRINT 10, N

10 FORMAT (1X,A2)

END

The top line says N is the string ‘UP’. The next line says to print N, using the format in line 10. The A2 format means a 2-character string. (The A is derived from the word Alphabet.) The computer will print:

UP

__Different versions__ Some computers allow apostrophes only in FORMAT, DATA, and CALL statements. (You’ll learn about CALL statements later.) On such computers, the statement N=‘UP’ is illegal. Instead say:

DATA N/'UP'/

__Restrictions__ A string statement should look like an integer: it should begin with the letter I, J, K, L, M, or N. You can say N=‘UP’ but shouldn’t say X= ‘UP’.

The string a variable stands for must be short. You can say N=‘UP’ but not N= ‘SUPERCALIFRAGILISTICEXPIALIDOCIOUS’. The longest permissible string depends on your computer:

__Computer__ __Longest string allowed__

PDP-11 (using FORTRAN IV) 2 characters

PDP-11 (using FORTRAN IV-PLUS), IBM 4 characters

PDP-10, PDP-20, Honeywell 5 characters

CDC 10 characters

__Fancy examples__ Examine this program:

PRINT 10

10 FORMAT (1X,'DO YOU LIKE ME?')

READ 20, IREPLY

20 FORMAT (A1)

IF (IREPLY .EQ. 'Y') PRINT 30

30 FORMAT (1X,'I LIKE YOU TOO!')

PRINT 40

40 FORMAT (1X,'SO LONG, BUSTER.')

END

The first pair of lines make the computer print DO YOU LIKE ME? The next pair set IREPLY equal to the first letter the human types. If the human types YESIREE, the computer will set IREPLY equal to `Y’ and will therefore print:

I LIKE YOU TOO!

SO LONG, BUSTER.

But if the human types NOT AT ALL, the computer will set IREPLY equal to `N’ and will therefore print just:

SO LONG, BUSTER.

In that program, the string is called IREPLY instead of REPLY, to make it an integer.

Advanced example:

DIMENSION NAME(25)

PRINT 10

10 FORMAT (1X,'WHAT IS YOUR NAME?')

READ 20, NAME

20 FORMAT (25A2)

PRINT 30, NAME

30 FORMAT (1X,'I HATE ANYONE NAMED ',25A2)

END

The top line says NAME will be a list of 25 elements. The next pair of lines print WHAT IS YOUR NAME? If the human answers —

BARTHOLOMEW HIERONYMOUS MCGILLICUDDY, M.D.

the format in line 20 sets NAME equal to 25 two-character strings:

NAME(1) is 'BA'

NAME(2) is 'RT'

NAME(3) is 'HO'

NAME(4) is 'LO'

NAME(5) is 'ME'

NAME(6) is 'W '

NAME(7) is 'HI'

NAME(8) is 'ER'

NAME(9) is 'ON'

NAME(10) is 'YM'

NAME(11) is 'OU'

NAME(12) is 'S '

NAME(13) is 'MC'

NAME(14) is 'GI'

NAME(15) is 'LL'

NAME(16) is 'IC'

NAME(17) is 'UD'

NAME(18) is 'DY'

NAME(19) is ', '

NAME(20) is 'M.'

NAME(21) is 'D.'

NAME(22) is ' '

NAME(23) is ' '

NAME(24) is ' '

NAME(25) is ' '

Format 30 prints:

I HATE ANYONE NAMED BARTHOLOMEW HIERONYMOUS MCGILLICUDDY, M.D.

To make that program run faster, use fewer strings. For example, if you have a CDC computer, each string can be as long as 10 characters, so you need only 5 strings to make 50 characters:

DIMENSION NAME(5)

PRINT 10

10 FORMAT (1X,'WHAT IS YOUR NAME?')

READ 20, NAME

20 FORMAT (5A10)

PRINT 30, NAME

30 FORMAT (1X,'I HATE ANYONE NAMED ',5A10)

END

__FORTRAN 77 strings__ On computer having FORTRAN 77, and on IBM computers using WATFIV, you can request super-long strings:

CHARACTER*50 NAME

PRINT 10

10 FORMAT (1X,'WHAT IS YOUR NAME?')

READ 20, NAME

20 FORMAT (A50)

PRINT 30, NAME

30 FORMAT (1X,'I HATE ANYONE NAMED ',A50)

END

The top line requests that NAME be a 50-character string. Like the DIMENSION statement, the CHARACTER statement must be put at the very top of the program, above even the DATA statements.

Functions

To do advanced math, use FORTRAN’s functions.

Square root

This program finds the square root of 9:

A=SQRT(9.0)

PRINT 10, A

10 FORMAT (1X,G14.6)

END

The computer will print:

3.00000

In that program, you must say SQRT(9.0), not SQRT(9). If you say SQRT(9), the computer will either gripe or print a wrong answer.

The number in parentheses must be real. That’s why you can say SQRT(9.0) but not SQRT(9). You can say SQRT(8.0+1.0) but not SQRT(8+1). You can say SQRT(X) but not SQRT(J).

Be careful when you translate from BASIC to FORTRAN: in BASIC, you say SQR; in FORTRAN, you say SQRT instead.

This program prints a table, showing the square root of 2.0, the square root of 3.0, the square root of 4.0, the square root of 5.0, etc.:

X=2.0

10 Y=SQRT(X)

PRINT 20, X,Y

20 FORMAT (1X,2G14.6)

X=X+1.0

GO TO 10

END

The computer will print:

2.00000 1.41421

3.00000 1.73205

4.00000 2.00000

5.00000 2.23607

6.00000 2.44949

7.00000 2.64575

8.00000 2.82843

9.00000 3.00000

10.0000 3.16228

etc.

FLOAT

If you say FLOAT, the computer will create a FLOATing-point number (in other words, a real number), by using an integer. For example, FLOAT(3) is 3.0. If J is 7, then FLOAT(J) is 7.0.

The word FLOAT can help you solve the following problems.…

__Find the square root of an integer J__ Unfortunately, you aren’t allowed to say SQRT(J), because what you take the square root of must be a real number. You can say SQRT(X) but not SQRT(J). *Solution:* say X=J, and then say SQRT(X). *Shorter solution:* say SQRT(FLOAT(J)).

__Divide J by K accurately__ Unfortunately, saying J/K gives an inaccurate answer, because when the computer divides integers it gives an integer answer, instead of an accurate real answer. *Solution:* say X=J, then Y=K, then X/Y. *Shorter solution:* say FLOAT(J)/FLOAT(K).

Random numbers

Here’s how to set R equal to a random decimal between 0 and 1:

__Computer__ __What to say__

CDC R=RANF(0)

PDP-10, PDP-11 R=RAN(0)

PDP-11 R=RAN(ISEED,ISEED2)

To randomize the random numbers on PDP-10 and PDP-20 computers, put these lines near the top of your program:

CALL TIME(ISEED,ISEED2)

CALL SETRAN(MOD(ISEED/2+ISEED2/2, 2147483648))

On other computers, randomizing is even more complicated; ask the people who run your computer center.

Maxima and minima

To find the maximum real number in a list, ask for AMAX1.

For example, AMAX1(4.7, 2.8, 41.6, 9.2, 82.3, 9.7) is 82.3. And AMIN1(4.7, 2.8, 41.6, 9.2, 82.3, 9.7) is the minimum, which is 2.8.

If the numbers in the list are integers, say MAX0 instead of AMAX1, and say MIN0 instead of AMIN1. When you type "MAX0" and "MIN0", make sure you end with a zero, not the letter "oh".

Absolute value

ABS(X) means the ABSolute value of X; in other words, X without its minus sign. For example:

ABS(-5.2) is 5.2

ABS(-7.0) is 7.0

ABS(9.3) is 9.3

For integers, say IABS instead of ABS. For example, IABS(-7) is 7.

Remainder

When you divide 11 by 4, the remainder is 3:

__ 2__

4 ) 11

__-8__

3 is the remainder

If you ask for MOD(11,4) the computer will divide 11 by 4 and get the remainder, which is 3; so MOD(11,4) is 3.

Use MOD for integers; use AMOD for reals. For example, AMOD(11.0, 4.0) is 3.0.

Trigonometry

If your computer has FORTRAN 77, or your computer is an IBM having FORTRAN H-EXTENDED, or your computer is a PDP-11 having FORTRAN IV-PLUS, you can use these trigonometric functions:

__Symbol__ __Meaning__

SIN(X) the SINe of X radians

COS(X) the COSine of X radians

TAN(X) the TANgent of X radians

ASIN(X) the ArcSINe of X in radians; the number whose sine is X

ACOS(X) the ArcCOSine of X in radians; the number whose cosine is X

ATAN(X) the ArcTANgent of X in radians; the number whose tangent is X

SINH(X) the SINe Hyperbolic of X

COSH(X) the COSine Hyperbolic of X

TANH(X) the TANgent Hyperbolic of X

If your computer is old-fashioned, it restricts you:

__Old-fashioned system__ __Restriction__

PDP-10, PDP-20 You can’t say TAN(X).

CDC You can’t say SINH(X) or COSH(X).

other IBM computers Say ARSIN(X) instead of ASIN(X). Say ARCOS(X) instead of ACOS(X).

FORTRAN IV computers You can’t say TAN(X), ASIN(X), ACOS(X), SINH(X), or COSH(X).

You can replace X by any *real* number. For example, you can say SIN(4.0) but not SIN(4); you can say SIN(Y) but not SIN(J).

Be careful when you translate from BASIC to FORTRAN: in BASIC, you say ATN; in FORTRAN, you say ATAN instead.

You’ve seen that SIN(X) is the sine of X *radians*. But what’s the sine of X *degrees*? On PDP-10 and PDP-20 computers, you can find the sine of X degrees by asking for SIND(X); and you can find the cosine of X degrees by asking for COSD(X).

ATAN2(Y,X) is about the same as ATAN(Y/X), but is faster, more accurate, and gives a useful answer even when X is zero or negative. ATAN2(Y,X) is the angle (in radians) of the line that goes through the origin and the point (X,Y).

Calculus

You can use these functions:

__Function__ __Meaning__

EXP(X) e^{X}

ALOG(X) log_{e} X

ALOG10(X) log_{10} X

You can replace X by any real number, but not by an integer. Each of those functions produces a *real* answer, since none of them begins with I, J, K, L, M, or N.

The logarithm function is called ALOG instead of LOG, to avoid beginning with L. Be careful when you translate from BASIC to FORTRAN: in BASIC, you say LOG; in FORTRAN, you say ALOG instead.

Exotic features

Let’s take off our handcuffs and go wild!

Let’s go beyond integers and reals, to other kinds of numbers that are wilder: double precision and complex.

Let’s go beyond standard functions and invent our *own* functions. Let’s go beyond standard statements and invent our *own* statements, by using subroutines and comments. Let’s go beyond the DATA statement and invent data *files*.

Here we go.…

Comments

If you type C instead of a line number, the computer will ignore the line.

N=50+13

C I HATE COMPUTERS!

PRINT 10, N

10 FORMAT (1X,I14)

END

The computer will ignore the Comment. The computer will print 63.

The C in FORTRAN is like the REMARK in BASIC: use it to document your program.

DOUBLE PRECISION

Some computers are more accurate than others:

__Computer__ __Accuracy for real numbers__

PDP-11, IBM 7 digits

PDP-10, PDP-20, Honeywell 8 digits

CDC 14 digits

For example, suppose you feed this program to a PDP-11 or IBM:

A=5398.1642376236

PRINT 10, A

10 FORMAT (1X,F15.10)

END

Expect the first 7 digits the computer prints to be correct (5398.164), but the remaining digits it prints to be wrong: they arise from round-off error inside the computer.

A PDP-11 or IBM prints *some* numbers to an accuracy of 8 digits and others to an accuracy of just 6 digits, but 7 digits is typical.

For real numbers, I recommend you use a G14.6 format, because it’s safe: it prints just the first 6 digits. If you want to see further digits that are probably correct, use these formats instead:

__Computer__ __Format__ __What the format does__

PDP-11, IBM G15.7 prints the first 7 digits

PDP-10, PDP-20, Honeywell G16.8 prints the first 8 digits

CDC G22.14 prints the first 14 digits

You can get extra accuracy by requesting double precision:

__Computer__ __Accuracy for double precision__ __Format__

PDP-11 14 digits D22.14

PDP-10 (using KA), Honeywell 16 digits D24.16

IBM 17 digits D25.17

PDP-10 (using KI or KL), PDP-20 18 digits D26.18

CDC 29 digits D37.29

Each of these programs computes the square root of 6.3x108 on a PDP-11 computer:

__Using reals__ __Using double precision__

DOUBLE PRECISION A

A=SQRT(6.3E8) A=DSQRT(6.3D8)

PRINT 10, A PRINT 10, A

10 FORMAT (1X,G15.7) 10 FORMAT (1X,D22.14)

END END

The program on the left computes 7 digits. The program on the right computes 14. Comparing the programs, you’ll notice four differences:

1. For double precision you must use double precision numbers. Instead of saying 6.3E8, say 6.3D8. The D means Double precision.

__Real number__ __Double precision__

6.3E8 6.3D8

29.6 29.6D0

this is a zero

2. For double precision, you must use double precision functions. Instead of saying SQRT, say DSQRT.

__Real function__ __Double precision__

SQRTD SQRT

AMAX1 DMAX1

AMIN1 DMIN1

ABS DABS

AMOD DMOD

EXP DEXP

ALOG DLOG

ALOG10 DLOG10

SIN DSIN

COS DCOS

TAN DTAN

ASIN DASIN

ACOS DACOS

ATAN DATAN

ATAN2 DATAN2

SINH DSINH

COSH DCOSH

TANH DTANH

3. For double precision, you must use double precision variables. Normally, the variable A would be real; to make it double precision instead, say:

DOUBLE PRECISION A

Normally, the variables LENGTH and MASS would be integers, and SPEED would be real; to make them all double precision, say:

DOUBLE PRECISION LENGTH,MASS,SPEED

Like the DIMENSION and CHARACTER statements, the DOUBLE PRECISION statement must be put at the very top of the program, above even the DATA statements. If you say —

IMPLICIT DOUBLE PRECISION(D)

every variable whose first letter is D will automatically be double precision; for example, DISTAN and DIAMET and DSIZE will automatically be double precision.

4. For double precision you must use double precision formats. Instead of a G format, use D22.14, or whichever D format is appropriate for your computer.

__Expense__ Although double precision arithmetic is more precise than real arithmetic, it’s also more expensive: it consumes more of the computer’s time, and the numbers consume more of the computer’s memory.

__Combinations__ If you combine an integer or a real number with a double precision number, the answer will be double precision.

COMPLEX

In mathematics, the square root of -1 is called i. So i^{2} is -1. The number i obeys most of the rules of algebra:

i+ i is 2i

2i+3i is 5i

(8+2i) + (7+3i) is 15+5i

(8+2i) * (7+3i) is 8*7 + 8*3i + 2i*7 + 2i*3i,

which is 56 + 24i + 14i + 6i^{2},

which is 56 + 24i + 14i + -6,

which is 50 + 38i

The number i is neither positive nor negative nor zero; it’s pictured instead as being above the real number line:

i

-5 -4 -3 -2 -1 0 1 2 3 4 5

2i is further above the real number line: it’s 2 units above 0. Another example: 5+2i is 2 units above 5.

A number that involves i is called complex. So 5+2i is complex. Its real part is 5, its imaginary part is 2, and its conjugate is 5-2i.

This program multiplies 8+2i by 7+3i and prints the correct answer, 50+38i:

COMPLEX B

B=(8.0, 2.0) * (7.0, 3.0)

PRINT 10, B

10 FORMAT (1X,2G14.6)

END

FORTRAN says (8.0, 2.0) instead of 8+2i. The decimal points and parentheses are required.

To make B complex instead of real, say COMPLEX B. Like the DIMENSION and CHARACTER and DOUBLE PRECISION statements, the COMPLEX statement must be put at the very top of the program, above even the DATA statements.

To print B, use the G14.6 format twice (once for the real part, and once for the imaginary part). The computer will print:

50.0000 38.0000

If you say IMPLICIT COMPLEX(C), every variable whose first letter is C will automatically be complex.

Although you can write 8+2i as (8.0, 2.0), you cannot write X+Yi as (X, Y); instead write CMPLX(X, Y).

Here’s the rule: to build a complex number from variables instead of from constants, say CMPLX. The variables that the complex number is built from must be real.

If B is complex, you can use these functions:

__Function__ __Meaning__

CSQRT(B) the complex number that’s the square root of B

CSIN(B) the complex number that’s the sine of B

CCOS(B) the complex number that’s the cosine of B

CEXP(B) the complex number that’s e^{B}

CLOG(B) the complex number that’s log B

CABS(B) the real number that’s the absolute value of B

REAL(B) the real number that’s the real part of B

AIMAG(B) the real number that’s the imaginary part of B

CONJG(B) the complex number that’s the conjugate of B

This program finds the square root of -9 and prints the correct answer, 3i:

COMPLEX B,Z

B=-9

Z=CSQRT(B)

PRINT 10, Z

10 FORMAT (1X,2G14.6)

END

Since the top line says B is complex, the second line makes B the complex number -9+0i. The next line makes Z the square root of -9+0i, which is 0+3i. The computer will print the 0 and the 3:

0.000000 3.00000

Since that program sets B equal to -9+0i, which FORTRAN writes as (-9.0, 0.0), you can shorten the program to this:

COMPLEX Z

Z=CSQRT( (-9.0, 0.0) )

PRINT 10, Z

10 FORMAT (1X,2G14.6)

END

Make sure the number inside CSQRT’s parentheses is complex: you need the decimal points, comma, and parentheses.

When the computer combines a complex number with an integer, a real, or a double precision number, the result is complex.

Some computers limit your use of complex numbers, by restrictions such as:

"Don’t say a complex number equals a double precision number."

"Don’t combine a complex number with a double precision number."

"Don’t raise a number to a complex power."

"Don’t raise a complex number to a power, unless the power is an integer."

Find out whether *your* computer has those restrictions.

Subroutines

This program is a combination of two routines:

PRINT 10

10 FORMAT (1X,'KIDS')

CALL YUMMY

PRINT 20

20 FORMAT (1X,'LOLLIPOPS')

END

SUBROUTINE YUMMY

PRINT 10

10 FORMAT (1X,'SUCK')

RETURN

END

Each routine ends with the word END.

The first routine is called the main routine.

The second routine is called the subroutine, and begins with the word SUBROUTINE. I decided to name it YUMMY, so its top line says SUBROUTINE YUMMY.

Above the word SUBROUTINE, I put a blank line. That blank line is optional; it helps humans find where the subroutine begins.

In the main routine, the top pair of lines makes the computer print:

KIDS

The next line says CALL YUMMY, which makes the computer skip down to subroutine YUMMY. Subroutine YUMMY makes the computer print —

SUCK

and then RETURN to the main routine, which finishes by printing:

LOLLIPOPS

Altogether, the program prints:

KIDS

SUCK

LOLLIPOPS

Notice that line 10 in the main routine is different from line 10 in the subroutine. Similarly, an X in the main routine is different from one in the subroutine:

X=3.4

CALL FUNNY

PRINT 10,X

10 FORMAT (1X,G14.6)

END

SUBROUTINE FUNNY

X=925.1

Y=X+1.0

PRINT 10, Y

10 FORMAT (1X,G14.6)

RETURN

END

The computer will set the main routine’s X equal to 3.4. Then it will call FUNNY. The X in FUNNY is 925.1, so Y is 926.1, and the computer will print:

926.100

When the computer returns to the main routine, it will print the main routine’s X, which is still:

3.40000

__Pass information between routines__ To pass information from one routine to another, put the information in parentheses:

A=5.2

CALL LEMON(A)

PRINT 10, A

10 FORMAT (1X,G14.6)

END

SUBROUTINE LEMON(X)

PRINT 100, X

100 FORMAT (1X,G14.6)

X=7.1

RETURN

END

The computer sets A equal to 5.2. Then it calls LEMON. The A and X in parentheses mean: the main routine’s A is the subroutine’s X, so the subroutine’s X is 5.2. Line 100 prints:

5.20000

The next line changes X to 7.1. When the computer returns to the main routine, the main routine’s A is the subroutine’s X, so the main routine’s A is 7.1. Line 10 prints:

7.10000

A harder example:

P=2.1

CALL JUNK(P)

PRINT 10, P

10 FORMAT (1X,G14.6)

END

SUBROUTINE JUNK(P)

P=3.0*P

RETURN

END

The computer sets P equal to 2.1 and then calls JUNK. The P in parentheses means: the main routine’s P is the subroutine’s P. The subroutine triples P, so P becomes 6.3. When the computer returns to the main routine, line 10 prints:

6.30000

Another example:

Q=1.4

CALL FAT(5.0, Q+.3, R)

PRINT 10, R

10 FORMAT (1X,G14.6)

END

SUBROUTINE FAT(X, Y, Z)

Z=X+Y

RETURN

END

When the main routine calls FAT, the subroutine’s X is 5.0; Y is Q+.3, which is 1.7; and Z is R, which is undefined. The subroutine sets Z equal to X+Y, which is 6.7. When the computer returns to the main routine, the main routine’s R is the subroutine’s Z, which is 6.7. Line 10 prints:

6.70000

In that CALL, you must say 5.0, not 5, since X must be real. Saying 5 will confuse the computer and make it print a wrong answer.

__Sum & average of a trio__ This subroutine finds the sum and average of three real numbers — X, Y, and Z:

SUBROUTINE STAT(X, Y, Z, SUM, AVERAG)

SUM=X+Y+Z

AVERAG=SUM/3.0

RETURN

END

This main routine uses STAT to find the sum and average of 8.1, 2.6, and 9.3:

CALL STAT(8.1, 2.6, 9.3, SUM, AVERAG)

PRINT 10, SUM,AVERAG

10 FORMAT (1X,2G14.6)

END

This subroutine finds the sum and average of three *double precision* numbers:

SUBROUTINE DSTAT(X, Y, Z, SUM, AVERAG)

DOUBLE PRECISION X, Y, Z, SUM, AVERAG

SUM=X+Y+Z

AVERAG=SUM/3D0

RETURN

END

This main routine uses DSTAT to find the sum and average of p , e, and my phone number (6662666):

DOUBLE PRECISION SUM, AVERAG

CALL DSTAT(3.1415926535898D0, 2.7182818284590D0, 6662666D0, SUM,

6AVERAG)

PRINT 10, SUM, AVERAG

10 FORMAT (1X,2D22.14)

END

You must say DOUBLE PRECISION in both the main routine and the subroutine.

__Sum & average of a long list__ This subroutine finds the sum and average of X1, X2, X3, …, XN:

SUBROUTINE STAT2(X, N, SUM, AVERAG)

DIMENSION X(N)

SUM=0.0

DO 10 I=1,N

SUM=SUM+X(I)

10 CONTINUE

AVERAG=SUM/N

RETURN

END

This main routine uses STAT2 to find the sum and average of 8.4, 9.6, 20.1, 7.2, 91.5, and 3.6:

DIMENSION X(6)

DATA X/8.4,9.6,20.1,7.2,91.5,3.6/

CALL STAT2(X, 6, SUM, AVERAG)

PRINT 10, SUM,AVERAG

10 FORMAT (1X,2G14.6)

END

You must put the DIMENSION statement in both the main routine and the subroutine. In the main routine, the DIMENSION must be a constant (6); in the subroutine, the DIMENSION can be a variable (N).

This main routine asks you to input some numbers, then prints their sum and average by using STAT2:

DIMENSION X(100)

PRINT 10

10 FORMAT (1X,'HOW MANY NUMBERS WOULD YOU LIKE TO GIVE ME?')

READ *, N

PRINT 20

20 FORMAT (1X,'TYPE THE NUMBERS')

READ *, (X(I), I=1,N)

CALL STAT(X, N, SUM, AVERAG)

PRINT 10, SUM,AVERAG

10 FORMAT (1X,'THE SUM IS',G14.6,' AND THE AVERAGE IS',G14.6)

END

That DIMENSION statement lets you input up to 100 numbers.

If a main routine says DIMENSION X(100), and X is passed between the main routine and the subroutine, the subroutine’s DIMENSION statement must say no more than X(100): if the subroutine’s DIMENSION statement says X(N), the N must be no more than 100.

__Pass double subscripts__ For *double* subscripts, the main routine’s DIMENSION statement must be *exactly* the same as the subroutine’s.

For example, suppose the main routine says DIMENSION X(25,4). Then the subroutine must say DIMENSION X(25,4) also. The subroutine must not say DIMENSION X(20,3). If the subroutine says DIMENSION X(M,N), the M must be exactly 25.

__Famous subroutines__ The Scientific Subroutine Package (SSP) is a collection of subroutines written by IBM that do statistics, calculus, equation-solving, and advanced math. The Calcomp subroutines make the computer operate a Calcomp plotter (a device that draws fancy shapes on paper, by using a felt-tip or ballpoint pen).

Most big computers store the SSP and Calcomp subroutines on disk permanently. Ask the people in your computer center how to combine your own main routines with those subroutines, and how to put your *own* library of subroutines onto the disk.

__How to write a big program__ If you and your friends want to write a big program together, divide the problem into a main routine and several subroutines. Have each person write one routine.

Although you’ll need a group conference to decide what the SUBROUTINE and CALL statements will be, you don’t have to agree on the names of variables, since the names of subroutine variables have nothing to do with the names of main-routine variables.

Your own functions

Instead of using functions such as SQRT and ABS, you can invent your *own* functions. Here’s how to invent a function called F, and how to use the function you’ve invented:

A=F(5.2)+1.0

PRINT 10, A

10 FORMAT (1X,G14.6)

END

FUNCTION F(X)

F=2.0*X

RETURN

END

The program consists of two routines. The first routine is the *main* routine. The second routine is the definition of the FUNCTION F. Each routine ends with the word END.

The main routine’s top line requires the computer to find F(5.2), so the computer hunts for the definition of FUNCTION F. The definition says F is twice 5.2, which is 10.4. So A is 11.4. The computer will print:

11.40000

Like a subroutine, a function definition can be very long and have many variables in parentheses.

__Naming your function__ You can give your function the name F or G or any other name, such as MASS. If the function’s name begins with I, J, K, L, M, or N, the computer will assume its value is an integer.

If you want the function MASS(X) to be double precision instead of an integer, begin your main routine by saying —

DOUBLE PRECISION MASS

and begin your function definition with this line:

DOUBLE PRECISION FUNCTION MASS(X)

Files

The computer can write its answers onto a data file:

A=14.6+75.2

WRITE(3,10) A

10 FORMAT (1X,G14.6)

WRITE(7,20)

20 FORMAT (1X,'TINA, PLEASE TICKLE MY TUBA')

END

Since A is 89.8, the second line makes the computer write 89.8 onto "file 3", using line 10’s format. The next pair of lines make the computer write onto "file 7", using line 20’s format; so the computer will write TINA, PLEASE TICKLE MY TUBA onto file 7.

Before running that program, tell the computer where to put files 3 and 7. You can make the computer put them on a disk, line printer, tape, terminal, or wherever else you please. Ask the people in your computer center how to tell the computer where to put the files.

If your program has many statements saying to write onto file 3, the computer will write many lines onto file 3, so the file will become long.

Use carriage controls only if the file is on a line printer or terminal.

If you say —

READ(4,30) X

the computer will read the value of X from file 4, using line 30’s format. If you say file 4 is the card reader, the computer will wait for you to feed in a card; it you say file 4 is your terminal, the computer will wait for you to type on the terminal; if you say file 4 is on a tape or disk, the computer will assume you created the file before running the program.

For handling files, the word READ works even on PDP computers.

For PDP-10 and PDP-20 computers, here’s how to make file 3 be on disk and named JOE.… Near the beginning of your program, say:

OPEN(UNIT=3, DEVICE='DSK', FILE='JOE.')

Near the end of your program, say:

CLOSE(UNIT=3)