Fortran DO循环,警告仅使用整数
我在Ubuntu 15.04系统上安装了gfortran。编译Fortran代码时,DO循环要求只获取整数参数,而不获取实数值或变量。其中包括循环变量和步长表达式。为什么不能也要真正的价值呢 以下是取自嵌套do循环一节练习3.5的程序 编译后显示的错误为:Fortran DO循环,警告仅使用整数,fortran,fortran90,gfortran,fortran95,Fortran,Fortran90,Gfortran,Fortran95,我在Ubuntu 15.04系统上安装了gfortran。编译Fortran代码时,DO循环要求只获取整数参数,而不获取实数值或变量。其中包括循环变量和步长表达式。为什么不能也要真正的价值呢 以下是取自嵌套do循环一节练习3.5的程序 编译后显示的错误为: 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
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
或
最后,您提到了.f90
和.f95
文件后缀。gfortran并不认为第一个标准意味着源代码遵循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\u real
的循环有效,但名为loop\u integer
的循环无效。在迭代计数的计算中,三个表达式被转换为循环变量的种类和种类参数INT(0.5)
is0
我已经回答了Fortran兼容程序必须使用整数变量/表达式的问题,但是请注意,编译器非常乐意使用reals。这些只是警告。我强烈建议你注意这些,但这对你来说仍然是一个不可携带的选择。哦,对了!这是一个警告。很好地指出。伟大的谢谢。但是为什么你说它是不可移植的呢?它是不可移植的,因为Fortran 95+编译器不需要接受程序,因为它不遵循标准规定的规则。有可能许多具有Fortran 77/90传统的当前编译器都有代码可以接受它,但这并不是我会努力投入到一个全新的编译器中的东西。这不是我推荐的,而是您可以转换为do while
循环(假设您想尝试模仿一些旧代码的行为)有趣的是,教程声称代码是F95+。。应该有人让他们知道。(他们希望你“注册”只是为了给他们发个便条)但必须是10。不是吗?我不认为fortran会评估到9或11.0.1在许多实现中并不完全可表示。如果精确值为0.9999或1.00001,则会从彼此和精确值确实为0.1的迭代计数中获得不同的迭代计数。请注意,INT
是用截断定义的,而不是最近的四舍五入。[上面有一个由一个向外的错误,同样:简单的答案是11.]如果.1
稍微加上四舍五入,你会得到10次迭代,停在略高于0.9的位置。如果精确或稍微向下舍入,则得到预期的11次迭代。我不知道怎么会是9岁。@agentp我的评论确实是错的。我奇怪的一点是,你根本不知道这一点。这将是一个糟糕的实现,但它可能会发生。其他情况可能比这更极端。
y = 1
do
if (y>4) exit
...
y = y+0.5
end do
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