Guess the number in FORTRAN 77
New computer science graduates are excited to work in Go or Rust or Python – the modern languages they learned during their program – only to be tasked to support a legacy programming language like FORTRAN. And there’s a lot of FORTRAN 77 out there, especially in the engineering and science fields. Learning some FORTRAN 77 can take you a long way.
But FORTRAN 77 doesn’t have to be all dull work. You can have fun with it too! Let’s exercise FORTRAN 77 by writing the classic “guess the number” game, where the computer generates a random, secret value from 1 to 100, and you must guess what it is.
The “guess the number” game exercises several concepts in programming, including how to declare variables, how to store values, how to print text, how to read input, and how to compare numbers.
The basics of FORTRAN 77
FORTRAN is a very old language, probably the oldest compiled “high level” language that’s still around. The first FORTRAN (formula translation) was released in the 1950s, FORTRAN-II and FORTRAN-III in the late 1950s, FORTRAN 66 in 1966, and FORTRAN 77 in 1977. Later versions changed the spelling to “Fortran,” starting with Fortran 90, which was meant to be codified in 1990 but wasn’t available until 1991. I learned FORTRAN 77 as an undergraduate physics student in the early 1990s, so that’s the version that I remember.
Old-style FORTRAN statements were originally written on punched cards, and the language retains some historical limitations because of that. For example, FORTRAN 77 statements could only be written in all uppercase. Also, FORTRAN 77 uses significant columns: the first five columns on a line were reserved for a statement label, which was just a number. Entering C
or *
in the first column indicated a comment line.
A number or one of a few other recognized characters in column six indicated a continuation, and that “card” or statement was tacked onto the previous one. Program instructions could only be written from column 7 to 72; columns 73 to 80 were reserved for card sorting, such as when you dropped a stack of punched cards on the floor and needed to use a card sorting machine to put them back into order.
Due to the limited amount of space on each card to write program instructions, old-style FORTRAN could ignore spaces between keywords and names. But I’ll use spaces in this example to keep things more clear.
Program structure
You define FORTRAN 77 programs using the PROGRAM
keyword, and terminate them with the END
keyword. You must give every program a name, starting with a letter and followed by one or more letters or numbers. In the simplest example, you might define an empty program called TEST
like this:
PROGRAM TEST
END
Declaring variables and storing values
FORTRAN 77 provided several variable types, including INTEGER
for whole numbers and REAL
for floating point values. Variable names started with a letter, and could be letters or numbers after that. For example, to declare a variable called COUNT
as an INTEGER
, you would write:
INTEGER COUNT
If you wanted to define more than one variable at a time, but of the same type, you separated the names with commas:
INTEGER COUNT,TOTAL
To store a value in a variable, use the equal sign. For example, type this to store the value 0 in the variable called TOTAL
:
TOTAL = 0
Comparing values
FORTRAN supports several ways to compare values. The most basic is number comparisons, such as these:
Comparison | What it means |
---|---|
.LT. | Less than |
.GT. | Greater than |
.LE. | Less than or equal |
.GE. | Greater than or equal |
.EQ. | Equal |
.NE. | Not equal |
Use the IF
statement with these comparisons. You can write IF
statements as a one-line instruction or as a block. The simplest and oldest syntax is the one-line statement, like this to jump to (GO TO
) a line label if a value is greater than zero:
IF (TOTAL .GT. 0) GOTO 10
With the one-line IF
statement, if the comparison isn’t true, then nothing happens. So the program will only jump to label 10 if the value in TOTAL
is greater than zero. For values zero or less, FORTRAN 77 executes the next statement in the program.
You can also use a block IF
statement. These use the THEN
keyword to start the block, and END IF
to end the block. For example, to increment a counter if it’s less than ten, you could write this IF
block:
IF (COUNT .LT. 10) THEN
COUNT = COUNT + 1
END IF
Simple arithmetic
This statement also shows how to use variables and values with simple arithmetic. FORTRAN supports these operations:
Operation | What it does |
---|---|
+ | Add |
- | Minus |
* | Multiply |
/ | Divide |
Arithmetic operations are always done in proper math order: parentheses are evaluated first, then multiplication and division, then addition and subtraction. For example, to calculate Newton’s equation of motion (a staple in physics) using some predefined values, you could enter this FORTRAN 77 statement:
PROGRAM NEWTON
REAL Y,Y0,V0,T,G
C INITIALIZE VARIABLES
Y0 = 10.0
V0 = 0.0
T = 1.0
G = 9.8
C CALCULATE RESULT
Y = Y0 + V0 * T + .5 * G * T * T
END
Because FORTRAN was created to make it easier to solve formulas, and because formulas often include exponents, FORTRAN 77 also supports “powers” or exponents using **
. These take the same level of precedence as parentheses. You could rewrite Newton’s calculation with an exponent, like this:
Y = Y0 + V0 * T + .5 * G * T**2
Functions and subroutines
FORTRAN 77 provides a collection of standard library functions that help you do your work. Functions take one or more values and return a single value. You might guess that many functions are mathematical in nature, like COS
for cosine and SIN
for sine. But you can find other functions for all kinds of things, including random values.
The RAND
function generates a random number from 0 to 1 (although it never reaches 1, so the maximum value is like 0.999…) For historical reasons, the RAND
function takes an argument: 0 if it should return the next pseudo-random number in the sequence, or 1 if it should restart the random number generator.
Before you can use the random number generator in FORTRAN 77, you need to initialize it with a seed value. You do this with a subroutine called SRAND
, and give it a seed number. To use a subroutine, use the CALL
keyword, then the name of the subroutine. For example, to seed the random number generator with a predetermined value, then print a few random numbers, you might write this sample program:
PROGRAM RAND000
CALL SRAND(23456)
PRINT *, RAND(0)
PRINT *, RAND(0)
PRINT *, RAND(0)
END
The PRINT
instruction prints one or more values using a format statement. In simple programs, you can get away with using *
to indicate a default format, where FORTRAN 77 will just print the value in a way that seems to make sense.
In the above program, each PRINT
statement prints a single number. To print all three random numbers on one line, you can separate the values with a comma:
PRINT *, RAND(0), RAND(0), RAND(0)
A program to guess a number
We can put all this together to write a fun program to guess a random number. In this program, the computer picks a random number from 1 to 100, then the user must guess the number. After each guess, the program prints “too low” or “too high” to help the user with their next guess. If the user guesses the secret number, the program prints “that’s right!’
PROGRAM GUESS00
INTEGER SECRET,GUESS,SEED
C F77 REQUIRES YOU TO PROVIDE YOUR OWN SEED TO THE RND NUM GENERATOR
PRINT *, 'ENTER A RANDOM SEED:'
READ *, SEED
CALL SRAND(SEED)
SECRET = INT(RAND(0)*100)+1
C GUESS THE NUMBER
PRINT *, 'GUESS THE RANDOM NUMBER FROM 1 TO 100'
10 PRINT *, 'YOUR GUESS?'
READ *, GUESS
IF (GUESS.LT.SECRET) PRINT *, 'TOO LOW'
IF (GUESS.GT.SECRET) PRINT *, 'TOO HIGH'
IF (GUESS.NE.SECRET) GOTO 10
PRINT *, 'THATS RIGHT!'
END
I’ve added comment lines to help break up the program into more understandable parts. The first two lines define the program with the PROGRAM
keyword, and define a list of variables for the secret number, the user’s guess, and the random number seed.
After that, the program prompts the user for a random number seed, and initializes the random number generator with the SRAND
subroutine. Then it uses the RAND
function to generate a random value; the program multiplies the random number by 100, giving a random value between 0 and 99.999… Taking the integer of that value gives a random number from 0 to 99. Adding one gives a final random number between 1 and 100.
The rest of the statements do the main body of work. The program prints a prompt, then reads the user’s guess with READ
. Two IF
statements tell the user if their guess was too low or too high. A third IF
statement jumps back to the prompt statement if the user hasn’t yet guessed the secret number
The program continues to the final PRINT
statement only when the user’s guess matches the secret random number. And that’s where the program ends.
Playing the game
Let’s compile the program using the GNU Fortran compiler, part of the GNU Compiler Collection. If you don’t have this installed on your system, most Linux distributions should provide it as a package that you can install like this:
$ sudo dnf install gcc-gfortran
Save the program as guess.f
and compile it with the gfortran
command. Because my program is written in classic FORTRAN 77, I’ve used the -std=legacy
option so the compiler doesn’t complain about any old-style syntax.
$ gfortran -std=legacy -o guess guess.f
When you run the program, you’ll be prompted to enter a seed value for the random number generator; enter any integer, usually a large value.
$ ./guess
ENTER A RANDOM SEED:
3456
GUESS THE RANDOM NUMBER FROM 1 TO 100
YOUR GUESS?
50
TOO HIGH
YOUR GUESS?
25
TOO HIGH
YOUR GUESS?
15
TOO HIGH
YOUR GUESS?
5
TOO HIGH
YOUR GUESS?
1
TOO LOW
YOUR GUESS?
3
THATS RIGHT!
Keep exploring
The “guess the number” game is a great introduction to programming, and it’s often one of the first programs I write when exploring a new programming language. Use this as a starting point to learn more about classic programming with FORTRAN 77.