Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make the loop counter not be greater than the final value?

So sample loop:

do i=1,1
    print *,i
enddo
print *,i

gives me 2 as the final value of i. How can I set up Intel Fortran for Visual Studio on Windows to give me a final value of 1 for i?

like image 548
Soumya Avatar asked Dec 16 '22 20:12

Soumya


1 Answers

This has been the way that Fortran loops work for decades and you can't simply change this with a compiler option. The Fortran standard clearly states:

8.1.4.4.1 Loop initiation

(2) The DO variable becomes defined with the value of the initial parameter m1.

(3) The iteration count is established and is the value of the expression MAX (INT ((m2 – m1 + m3) / m3), 0)

Here m1, m2 and m3 are the three parameters in the loop-control: [,] var = m1,m2[,m3], Given your example of i=1,1 (m3 is implicitly 1 if omitted) the iteration count is MAX(INT((1-1+1)/1),0) which evaluates to 1, i.e. the loop should get executed once. i is initialised to 1 as per (2).

8.1.4.4.2 The execution cycle

The execution cycle of a DO construct consists of the following steps performed in sequence repeatedly until termination:

(1) The iteration count, if any, is tested. If the iteration count is zero, the loop terminates and the DO construct becomes inactive. If loop-control is [ , ] WHILE (scalar-logical-expr), the scalar-logicalexpr is evaluated; if the value of this expression is false, the loop terminates and the DO construct becomes inactive. If, as a result, all of the DO constructs sharing the do-term-shared-stmt are inactive, the execution of all of these constructs is complete. However, if some of the DO constructs sharing the do-term-shared-stmt are active, execution continues with step (3) of the execution cycle of the active DO construct whose DO statement was most recently executed.

Fortran tests if the remaining iteration count is greater than zero, not if the DO variable is less than (greater than) the end value.

(2) If the iteration count is nonzero, the range of the loop is executed.

(3) The iteration count, if any, is decremented by one. The DO variable, if any, is incremented by the value of the incrementation parameter m3.

The DO variable is always incremented as an iteration of the loop is being executed. Thus after the first execution i becomes incremented by 1 which evaluates to 2.

Except for the incrementation of the DO variable that occurs in step (3), the DO variable must neither be redefined nor become undefined while the DO construct is active.

8.1.4.4.4 Loop termination

When a DO construct becomes inactive, the DO-variable, if any, of the DO construct retains its last defined value.

The last defined value is 2. Thus after the DO loop has ended, i is equal to 2.

I've pulled the text out of ISO/IEC 1539:1991 (a.k.a. Fortran 90) but one can also find pretty much the same text in §11.10.3 of ISO/IEC 1539:1980 (a.k.a. ANSI X3J3/90.4 a.k.a. FORTRAN 77; sans the WHILE stuff which is not present in F77) as well as in §8.1.6.6 of ISO/IEC 1539-1:2010 (a.k.a. Fortran 2008).

like image 51
Hristo Iliev Avatar answered Dec 25 '22 23:12

Hristo Iliev