Fortran DO loop, warning to use integer only

删除回忆录丶 提交于 2021-02-15 11:08:55

问题


I installed gfortran on my Ubuntu 15.04 system. While compiling Fortran code, the DO loop asks to take integer parameters only and not real values or variables. That includes the loop variable and the step expression. Why can't it take real values too?

The following is a program taken from here, exercise 3.5 of the section nested do loops.

        program  xytab
        implicit none
        !constructs a table of z=x/y for values of x from 1 to 2 and 
        !y from 1 to 4 in  steps of .5
        real         ::   x, y, z 
        print *, '           x           y           z'
        do  x = 1,2
            do y = 1,4,0.5
                z = x/y
                print *, x,y,z
            end do
        end  do
        end  program xytab

The error shown after compiling is:

xytab.f95:8.4:

 do y = 1,4,0.5
    1
Warning: Deleted feature: Loop variable at (1) must be integer
xytab.f95:8.12:

 do y = 1,4,0.5
            1
Warning: Deleted feature: Step expression in DO loop at (1) must be integer
xytab.f95:7.3:

do x = 1,2
   1
Warning: Deleted feature: Loop variable at (1) must be integer

回答1:


The Fortran standard now requires that a do construct's loop control is given by (scalar) integer expressions and that the loop variable is a (scalar) integer variable. The loop control consists of the start, step, and stop expressions (your step expression is 0.5). See R818 and R819 (8.1.6.2) of the Fortran 2008 document. That, then, is the short and simple answer: the standard says so.

It's a little more complicated than that, as the messages from the compiler suggest. Using other forms for loop control was present in Fortran up until Fortran 95. That is, from Fortran 95 onward using real expressions is a deleted feature.

What harm is there in using real expressions? Used correctly, one could imagine, there is no harm. But there's real difficulty in portability with them.

Consider

do x=0., 1., 0.1
 ...
end do

How many iterations? That would be (under the rules of Fortran 90) MAX(INT((m2 – m1 + m3) / m3), 0) where (m1 is the start value (0.), m2 the stop value (1.) and m3 the step value (0.1)). Is that 10 or 11 (or even 9)? It depends entirely on your numeric representation: we recall that 0.1 may not be exactly representable as a real number and INT truncates in converting to integer. You'd also have to worry about repeated addition of real numbers.

So, use integers and do some arithmetic inside the loop

do y_loop = 0, 6
  y = 1 + y_loop/2.
  ...
end do

or

y = 1
do
  if (y>4) exit
  ...
  y = y+0.5
end do

Finally, you mention .f90 and .f95 file suffixes. gfortran doesn't take the first to mean that the source code follows the Fortran 90 standard (where the code would be fine). Further, the messages from the compiler are merely warnings, and these can be suppressed using the -std=legacy option. Conversely, using -std=f95 (or later standards) these become errors.


As a bonus fun fact consider the following piece of Fortran 90 code.

real y
integer i

loop_real: do y=1, 4, 0.5
end do loop_real

loop_integer: do i=1, 4, 0.5
end do loop_integer

While the loop named loop_real is valid, that named loop_integer isn't. In the calculation of the iteration count the three expressions are converted to the kind, with kind parameters, of the loop variable. INT(0.5) is 0.



来源:https://stackoverflow.com/questions/30707668/fortran-do-loop-warning-to-use-integer-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!