我想反复增加我的变量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
不是一成不变的。
答案 0 :(得分:0)
添加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,他指出了我的方向。