我想反复增加我的变量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 = 0
和time_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谁为我指明了这个方向。