Values, types and arithmetic
The four everyday types — integer, real, character and logical — how to declare them, and the arithmetic rule that catches everyone: integer division throws the remainder away.
Declaring what a name holds
A Fortran variable is declared before it is used, on a line of its own: the type, then ::, then the names, separated by commas. integer :: apples, people makes two integer variables. Nothing is assigned yet — a variable that has been declared but not set holds whatever was in memory, which is one more reason implicit none is not the only habit worth having.
The type decides three things at once: what operations make sense, how much room the value takes, and how it prints. That is why Fortran makes you say it up front rather than inferring it from the first assignment.
Four types carry most programs
integer is a whole number. real is a decimal number, single precision by default — around seven significant digits, which is plenty for an average and not enough for money. character(len=20) is text of a fixed length: the value is padded with blanks when it is shorter and truncated when it is longer, silently in both directions.
logical is a yes or no, written .true. and .false. with the dots — the dots are part of the constant, and dropping them turns it into an undeclared name. Fortran also has complex and double precision, and a modern way of asking for a specific width with real(kind=...); none of them are needed for the chapters ahead.
An integer is not unbounded. The default kind is usually 32 bits, so the largest value is a little over two billion, and arithmetic past that can wrap to a negative number without a warning. huge(1) prints the limit for the default kind; if a count can approach it, declare a wider kind or keep the total in a real where precision, not range, is the limit.
Character comparison follows the machine’s collating sequence, which is close to alphabetical for plain ASCII but puts uppercase letters before lowercase ones. That is why a sorted list of names can begin with all the capitals; folding case before comparing is a decision the program has to make.
Integer division, and how to escape it
When both sides of / are integers, the answer is an integer and the remainder is dropped: 7 / 2 is 3, not 3.5. This is not a bug and it is not rounding — it is the definition of division on whole numbers, and Fortran keeps it even when the answer is stored in a real.
mod(7, 2) returns the remainder, 1, which is how a loop asks "is this even". To get a real division, one side must be real: real(apples) / people converts first, then divides. In a mixed expression Fortran promotes the integers, so price * apples with a real price is already real arithmetic.
Precedence is the arithmetic you already know: ** first, then * and / left to right, then + and -. Parentheses are free and worth using when a formula is translated from paper, because a missing pair is a wrong answer that still compiles.
The same numbers, two ways to divide
integer :: apples, people
real :: share
apples = 7
people = 2
share = apples / people ! 3.0 - the remainder is gone
print *, share
share = real(apples) / people ! 3.5
print *, share
print *, mod(apples, people) ! 1What assignment does to a type
Assignment converts when the types differ, and one direction loses information. Putting a real into an integer truncates toward zero — int(8.9) is 8 and int(-8.9) is -8 — and n = 3.9 does the same without the function call. The compiler may warn, but the program runs and the fraction is gone.
The other direction is safe in value and not in precision. An integer assigned to a real is represented exactly up to about sixteen million; beyond that, single-precision reals keep only about seven significant digits, so a large count can come back rounded. That is the same limit that makes real a poor choice for money, and the reason later chapters keep totals in integers where they can.
Three errors worth recognising on sight: a variable that is declared but never set, so it prints whatever was left in memory; a division that should keep a fraction but has integers on both sides; and a real used to hold money. The first is why every example here assigns before it prints, the second needs real(...) on one side, and the third needs cents in an integer.
Try these next
- Declare a
realand aninteger, assign 3.9 to both, and print them. - Print
huge(1),huge(1.0)andepsilon(1.0)and read what each limit means. - Average 7, 8 and 10 with integer division and with
real, and compare the two answers.
Watch the remainder disappear
Run it and compare the two division lines. Then change apples to 9 and people to 4, and add a line that prints the total with the price doubled.
Two means from the same total
Run it and compare the two means. Then set the scores to 9, 9 and 10 and predict both means before you run again.
Integer division is the first Fortran bug almost everyone writes: an average of integer scores comes out one whole number low or plain wrong, and nothing complains. If a division should keep its fraction, make one side real before you divide.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does 7 / 2 evaluate to when both values are integers?
