Fortran循环不工作
Fortran在运行此命令时返回一条错误消息,表示浮点溢出Fortran循环不工作,fortran,do-loops,Fortran,Do Loops,Fortran在运行此命令时返回一条错误消息,表示浮点溢出 program single implicit none integer :: n,k real, dimension(255) :: x n = 255 x(1) = 1/3.0 x(2) = 1/12.0 do k = 3,n x(k) = 2.25*x(k-1) - 0.5*x(k-2) end do print *,x end program 经过一些测试,我认为这是由于do循环中的变量索引造成的,但我不太明白问题是什么。
program single
implicit none
integer :: n,k
real, dimension(255) :: x
n = 255
x(1) = 1/3.0
x(2) = 1/12.0
do k = 3,n
x(k) = 2.25*x(k-1) - 0.5*x(k-2)
end do
print *,x
end program
经过一些测试,我认为这是由于do循环中的变量索引造成的,但我不太明白问题是什么。有人能帮我吗?通过在循环过程中打印
x
的值,您可以了解正在发生的事情。前几个值是
2.08333284E-02
5.20832092E-03
1.30205788E-03
3.25469766E-04
8.12780345E-05
2.01406947E-05
4.67754580E-06
4.54130713E-07
-1.31697880E-06
-3.19026776E-06
-6.51961273E-06
-1.30739954E-05
请注意符号是如何变化的,并且值从此处开始单调递增。您可能已经注意到,对于x
的负值,您定义的序列是指数增长的,因此,一旦您变为负值,指数增长会迅速影响您并导致浮点溢出,因为x
只是不断增长(在100次迭代之后,它已经超过1E+21
)
但是,让我们看看如果通过指定
Integer, Parameter :: wp = Selected_real_kind( 13, 70 )
real(kind=wp), dimension(255) :: x
如果我们现在编译并运行同一个程序,我们会注意到
x(k)
会变为0以增加k
,但在255次迭代中不会改变符号。因此,事实上,您看到的溢出是由浮点表示的精度不足引起的,这会导致错误的符号更改,并导致随后的指数增长。请不要向初学者教授(kind=8)
,它是非标准的,可能无法移植。除此之外,答案很好。我发现一个有趣的区别是,对于相同的选定类型,32位和64位编译器的结果不同。不确定是我使用的编译器(FTN95)还是32位和64位指令之间的不同舍入。64位FTN95和gFortran产生相同的结果。我还使用了“x(k)=(4.5*x(k-1)-x(k-2))/2”来查看这是否改变了舍入,但没有改变。更改为8字节实数删除了-ve结果,但32位/64位舍入差异仍然很明显。