0

我想反复增加我的变量time,并确保它与所有精确匹配的值是align_time.

目前我有一个功能

subroutine align(time, incr, align_time)
  real(8) time, incr, align_time

  if (modulo(time+incr,align_time) .lt. modulo(time,align_time)) then
      incr = align_time - modulo(time,align_time)
  end if

  time = time + incr
end subroutine

这可以称为

time = 0
align_time = 100
do while (time < 10000) 
    incr = cpt_incr(...)
    call align(time, incr, align_time) 
    ...
end do

问题是由于舍入错误,程序在某些时候挂起。说align_time是 0.1 在这一点time上等于 0.6-eps(eps 是机器 epsilon),当它应该是 0.6 时,则incr始终设置为 0。

我还应该提到,align_time在某些时候可能会发生变化,比如if (time > 1000) align_time = 200.

有人知道如何以避免舍入错误的方式解决问题吗?

[我真的对标签和标题没有任何好的想法,如果有,请编辑。此外,不想添加 Fortran,因为这同样适用于 C 或其他]

编辑:incr必须减小的值才能实现对齐,而不是增加。align_time可以比值大 100 倍,incr但也可以更小。incr不是恒定的。

4

1 回答 1

0

添加integer(8) itime = 0time_mult = huge(itime)/2/time_end 在我的初始化后,我将子程序更改为:

subroutine align(time, incr, align_time)
    real(8) time, incr, align_time
    integer(8) iincr, ialign

    iincr = nint(incr*time_mult, 8)
    ialign = nint(align_time*time_mult, 8)
    if (modulo(itime+idt,ialign) .lt. modulo(itime,ialign)) then
        iincr = ialign - modulo(itime,ialign)
    end if

    itime = itime + idt

    time = itime/time_mult
    incr = iincr/time_mult
end subroutine

一切似乎都奏效了。

归功于@KyleKanos,他为我指明了这个方向。

于 2013-10-16T22:05:03.030 回答