# Counting DO-Loop

There are two forms of loops, the counting loop and the general loop. The syntax of the counting loop is the following:

```DO control-var = initial-value, final-value, [step-size]
statements
END DO
```
where control-var is an INTEGER variable, initial-value and final-value are two INTEGER expressions, and step-size is also an INTEGER expression whose value cannot be zero. Note that step-size is optional. If it is omitted, the default value is 1. statements is a sequence of statements and is usually referred to as the body of the DO-loop. You can use any executable statement within a DO-loop, including IF-THEN-ELSE-END IF and even another DO-loop.

The following are a few simple examples:

• INTEGER variables Counter, Init, Final and Step are control-var, initial-value, final-value and step-size, respectively.
```INTEGER :: Counter, Init, Final, Step

DO Counter = Init, Final, Step
.....
END DO
```
• INTEGER variables i is the control-var. The initial-value and final-value are computed as the results of INTEGER expressions Upper-Lower and Upper+Lower, respectively. Since step-size is omitted, it is assumed to be 1.
```INTEGER :: i, Lower, Upper

Lower = ....
Upper = ....
DO i = Upper - Lower, Upper + Lower
.....
END DO
```
The meaning of this counting-loop goes as follows:
• Before the DO-loop starts, the values of initial-value, final-value and step-size are computed exactly once. More precisely, during the course of executing the DO-loop, these values will not be re-computed.
• step-size cannot be zero.
• If the value of step-size is positive (i.e., counting up):
1. The control-var receives the value of initial-value
2. If the value of control-var is less than or equal to the value of final-value, the statements part is executed. Then, the value of step-size is added to the value of control-var. Go back and compare the values of control-var and final-value.
3. If the value of control-var is greater than the value of final-value, the DO-loop completes and the statement following END DO is executed.
• If the value of step-size is negative (i.e., counting down):
1. The control-var receives the value of initial-value
2. If the value of control-var is greater than or equal to the value of final-value, the statements part is executed. Then, the value of step-size is added to the value of control-var. Go back and compare the values of control-var and final-value.
3. If the value of control-var is less than the value of final-value, the DO-loop completes and the statement following END DO is executed.

### Examples

• In the following, the control-var is Count. It receives -3 before the loop starts. It goes down the loop body and display the values of Count, Count*Count and Count*Count*Count. Thus, -3, 9, -27 are displayed. Then, 2 is added to Count changing its value from -3 to -1. Since this new value of Count (=-1) is less than the final-value, the loop body is executed and displays -1, 1, -1. Then, 2 is added to Count again, changing the value of Count to 1(=(-1)+2). Since this new value is still less than the final-value, the loop body is executed again. This time, it will display 1, 1, 1. Then, 2 is added to Count the third time, changing its value to 3. Since 3 is still less than the final-value, 3, 9, 27 are displayed. After adding 2 to the value of Count the fourth time, the new value of Count is finally greater than the final-value and the DO-loop completes.
```INTEGER  :: Count

DO Count = -3, 4, 2
WRITE(*,*)  Count, Count*Count, Count*Count*Count
END DO
```
• In the following, since steps-size is omitted, it is assumed to be 1. Therefore, the control-var Iteration receives 3, 4, and 5 in this order.
```INTEGER, PARAMETER :: Init = 3, Final = 5
INTEGER            :: Iteration

DO Iteration = Init, Final
WRITE(*,*)  'Iteration ', Iteration
END DO
```
• The following uses two Fortran intrinsic functions MIN() and MAX(). It is a count-down loop. The initial-value is the maximum of a, b and c, the final-value is the minimum of a, b and c, and the step-size is -2. Therefore, if the READ statement reads 2, 7, 5 into a, b and , then MAX(a,b,c) and MIN(a,b,c) are 7 and 2, respectively. As a result, control-var List will have values 7, 5, and 3.
```INTEGER :: a, b, c
INTEGER :: List

DO List = MAX(a, b, c), MIN(a, b, c), -2
WRITE(*,*)  List
END DO
```

### Frequently Used Loop Tricks

In addition to repeatedly processing some data as shown above, the DO-loop has some other uses as presented in the following examples:
• Adding numbers: Suppose the value of INTEGER variable Number has been given elsewhere, perhaps with a READ. The following code reads in Number integers and computes their sum into variable Sum.
```INTEGER :: Count, Number, Sum, Input

Sum = 0
DO Count = 1, Number
Sum = Sum + Input
END DO
```
Sum is initialized to zero. For each iteration, the value of Input, which is read in with READ, is added to the value of Sum.

For example, if the value of Number is 3, and the three input values are 3, 6, and 8 (on different lines), then the final value of Sum is 17 = 3+6+8. Let us look at it closely. Initially, Count receives a value of 1. Since 1 is less than the value of Number (=3), the loop body is executed. The READ statement reads the first input value 3 into Input and this value is added to Sum, changing its value from 0 to 1 (=0+1). Now, END DO is reached and the step-size (=1) is added to Count. Hence, the new value of Count is 2.

Since Count is less than Number, the second input value is read into Input. Now, Input holds 6. Then, 6 is added to the value of Sum, changing its value to 9 (=3+6). The next iteration reads in 8 and adds 8 to Sum. The new value of Sum becomes 17 (=9+8).

A simple modification can compute the average of all input numbers:

```INTEGER :: Count, Number, Sum, Input
REAL    :: Average

Sum = 0
DO Count = 1, Number
Sum = Sum + Input
END DO
Average = REAL(Sum) / Number
```
The above seems obvious. But, please note the use of the function REAL() that converts an INTEGER to a REAL. Without this conversion, Sum /Number is computed as dividing an integer by an integer, yielding an integer result. Consult singe mode arithmetic expressions for details.
• Factorial: A simple variation could be used to compute the factorial of a positive integer. The factorial of an integer N, written as N!, is defined to be the product of 1, 2, 3, ..., N-1, and N. More precisely, N! = N*(N-1)*(N-2)*...*3*2*1.
```INTEGER :: Factorial, N, I

Factorial = 1
DO I = 1, N
Factorial = factorial * I
END DO
```
In the above, the DO-loop iterates N times. The first iteration multiplies Factorial with 1, the second iteration multiplies Factorial with 2, the third time with 3, ..., the i-th time with I and so on. Therefore, the values that are multiplied with the initial value of Factorial are 1, 2, 3, ..., N. At the end of the DO, the value of Factorial is 1*2*3*...*(N-1)*N.

There are certain things you should know about DO-loops.
• The step-size cannot be zero. The following is not a good practice:
```INTEGER :: count

DO count = -3, 4, 0
...
END DO
```
• Do not change the value of the control-var. The following is not a good practice:
```INTEGER :: a, b, c

DO a = b, c, 3
READ(*,*)  a ! the value of a is changed
a = b-c      ! the value of a is changed
END DO
```
• Do not change the value of any variable involved in initial-value, final-value and step-size. The following is not a good practice:
```INTEGER :: a, b, c, d, e

DO a = b+c, c*d, (b+c)/e
READ(*,*) b          ! initial-value is changed
d = 5                ! final-value is changed
e = -3               ! step-size is changed
END DO
```
• When you have a count-down loop, make sure the step-size is negative. If you have a positive step-size, the body of the DO-loop will not be executed. See the way of executing a DO loop above. The body of the following DO will not be executed.
```INTEGER :: i

DO i = 10, -10
.....
END DO
```
• While you can use REAL type for control-var, initial-value, final-value and step-size, it would be better not to use this feature at all since it may be dropped in future Fortran standard. In the DO-loop below, x successively receives -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 and 1.0.
```REAL :: x

DO x = -1.0, 1.0, 0.25
.....
END DO
```
You should not use this form of DO-loop in your programs. See the discussion of general DO for the details.