使用Fortran计算循环内部

ast*_*y13 1 fortran

我有一些执行模拟的Fortran代码.经过的时间存储在et,并存储时间步长dt.两者都被定义为真实的类型.还有另一个真实变量tot,它保存模拟运行的最长时间. i是整数类型的计数变量.我的第一次尝试是这样的:

real, intent(in) :: dt
real, intent(in) :: tot

real :: et
integer :: i

et = 0.0
i = 0
do
   i = i+1
   et = real(i)*dt
   if (et > tot) exit

   ! main code here
end do
Run Code Online (Sandbox Code Playgroud)

我想摆脱i它,因为它只在一个地方使用,但是,当我尝试这个时,程序在总时间很长时挂起:

real, intent(in) :: dt
real, intent(in) :: tot

real :: et

et = 0.0
do
   et = et + dt
   if (et > tot) exit

   ! main code here
end do
Run Code Online (Sandbox Code Playgroud)

导致程序响应的两个代码示例有什么区别?我的编译器是g77.

编辑:我已将声明和初始化添加到上面的代码示例.

编辑2:传递给子程序的初始值是dt = 1e-6tot = 100.

ste*_*ert 5

我不知道这是不是你的错误,因为你不给整个程序,但在第一个代码中,你做的第一件事就是设置et等于dt,因为那时候i=1.然而,在第二个代码中,您正在使用et而没有设置它(据我们所知).而且,dt似乎未初始化使用.如果存储器地址处的字节et产生大的负浮点数,则可能需要更长的时间才能到达tot.如果没有更多的代码,那就是我能想到的东西.

编辑感谢您的更新.

那么在这种情况下我想只读哈德拉克的答案,我认为这是你的解决方案.如果你需要100通过加总来达到1.0e-6,这对4字节实数不起作用,因为在基数10中只有大约6-7个有意义的数字.你的第一个解决方案稍微好一点,因为你可以达到约2e9使用4字节的int.一种解决方案是使用8字节变量.但是,您应该始终构建一个额外的检查(例如if (et > tot .OR. i > max_iter))以允许最多的迭代,因此您可以安全地防范这一点,因为即使您使用整数解决方案,如果您将tot变大,您的整数可能会溢出并且你也将陷入无限循环.