Fortran DO 循环,警告仅使用整数
Fortran DO loop, warning to use integer only
我在 Ubuntu 15.04 系统上安装了 gfortran。在编译 Fortran 代码时,DO 循环要求只接受整数参数,而不是实数值或变量。这包括循环变量和步骤表达式。为什么它不能也取真实值?
以下程序摘自 here,第 嵌套 do 循环 .
部分的练习 3.5
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
编译后显示的错误为:
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
Fortran 标准现在要求 do 结构的循环控制由(标量)整数表达式给出,并且循环变量是(标量)整数变量。循环控件由开始、步骤和停止表达式组成(您的步骤表达式是0.5
)。请参阅 Fortran 2008 文档的 R818 和 R819 (8.1.6.2)。那么,这就是简短而简单的答案:标准是这样说的。
正如编译器的消息所暗示的那样,它比这要复杂一点。在 Fortran 95 之前,使用其他形式进行循环控制一直存在于 Fortran 中。也就是说,从 Fortran 95 开始,使用实数表达式是一项被删除的功能。
用真实的表情有什么坏处?使用得当,可想而知,没有坏处。但是它们的便携性确实很困难。
考虑
do x=0., 1., 0.1
...
end do
多少次迭代?那将是(根据 Fortran 90 的规则)MAX(INT((m2 – m1 + m3) / m3), 0)
其中(m1
是起始值 (0.
),m2
是停止值 (1.
)和 m3
步长值 (0.1
))。那是 10 还是 11(甚至 9)?这完全取决于您的数字表示:我们记得 0.1
可能不能完全表示为实数,并且 INT
在转换为整数时会截断。您还必须担心重复添加实数。
所以,使用整数并在循环内做一些算术运算
do y_loop = 0, 6
y = 1 + y_loop/2.
...
end do
或
y = 1
do
if (y>4) exit
...
y = y+0.5
end do
最后,你提到了.f90
和.f95
文件后缀。 gfortran 并没有把 first 当作源代码遵循 Fortran 90 标准(那里的代码会很好)。此外,来自编译器的消息仅仅是警告,可以使用 -std=legacy
选项来抑制这些消息。相反,使用 -std=f95
(或更高版本的标准)这些会变成错误。
作为额外的有趣事实,请考虑以下一段 Fortran 90 代码。
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
虽然名为 loop_real
的循环有效,但名为 loop_integer
的循环无效。在迭代计数的计算中,三个表达式被转换为循环变量的种类,带有种类参数。 INT(0.5)
是 0
.
我在 Ubuntu 15.04 系统上安装了 gfortran。在编译 Fortran 代码时,DO 循环要求只接受整数参数,而不是实数值或变量。这包括循环变量和步骤表达式。为什么它不能也取真实值?
以下程序摘自 here,第 嵌套 do 循环 .
部分的练习 3.5 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
编译后显示的错误为:
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
Fortran 标准现在要求 do 结构的循环控制由(标量)整数表达式给出,并且循环变量是(标量)整数变量。循环控件由开始、步骤和停止表达式组成(您的步骤表达式是0.5
)。请参阅 Fortran 2008 文档的 R818 和 R819 (8.1.6.2)。那么,这就是简短而简单的答案:标准是这样说的。
正如编译器的消息所暗示的那样,它比这要复杂一点。在 Fortran 95 之前,使用其他形式进行循环控制一直存在于 Fortran 中。也就是说,从 Fortran 95 开始,使用实数表达式是一项被删除的功能。
用真实的表情有什么坏处?使用得当,可想而知,没有坏处。但是它们的便携性确实很困难。
考虑
do x=0., 1., 0.1
...
end do
多少次迭代?那将是(根据 Fortran 90 的规则)MAX(INT((m2 – m1 + m3) / m3), 0)
其中(m1
是起始值 (0.
),m2
是停止值 (1.
)和 m3
步长值 (0.1
))。那是 10 还是 11(甚至 9)?这完全取决于您的数字表示:我们记得 0.1
可能不能完全表示为实数,并且 INT
在转换为整数时会截断。您还必须担心重复添加实数。
所以,使用整数并在循环内做一些算术运算
do y_loop = 0, 6
y = 1 + y_loop/2.
...
end do
或
y = 1
do
if (y>4) exit
...
y = y+0.5
end do
最后,你提到了.f90
和.f95
文件后缀。 gfortran 并没有把 first 当作源代码遵循 Fortran 90 标准(那里的代码会很好)。此外,来自编译器的消息仅仅是警告,可以使用 -std=legacy
选项来抑制这些消息。相反,使用 -std=f95
(或更高版本的标准)这些会变成错误。
作为额外的有趣事实,请考虑以下一段 Fortran 90 代码。
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
虽然名为 loop_real
的循环有效,但名为 loop_integer
的循环无效。在迭代计数的计算中,三个表达式被转换为循环变量的种类,带有种类参数。 INT(0.5)
是 0
.