对齐实际值时避免舍入问题



我想反复增加我的变量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可以比incr值大 100 倍,但也可以更小。 incr不是恒定的。

添加

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谁为我指明了这个方向。

最新更新