FORTRANで四捨五入
2013年8月22日
2019年5月30日
TRNSYSのコンポーネントを書いて、計算に組み込んでみたら、すかっと落ちる。
これがエラーメッセージが表示されるわけでもなく、ログにも手がかりなし。
調べてみると、どうも計算誤差が原因っぽい。
計算上は本来はゼロになる条件なのに、どうも誤差の積み重ねで変な値が出来上がっている。こういうのループの中で計算しているとありがちですよね。
ということで四捨五入
しょうがないので小数点以下の適当なところで四捨五入して誤差を吸収しようとしたら、FORTRANに適当な関数が無いんですね。(知らないだけか?)
ひとまず文字列に変換する処理で実装してみたんだけど、これだと遅くないかな?
みんなどうやってんだろう?なんか定石がありそうな気がする。
! 四捨五入
CONTAINS
DOUBLE PRECISION Function QRound(val)
DOUBLE PRECISION val
Character(20) valStr
write(valStr, '(f0.5)') val ! 実数を文字列に変換
read(valStr, *) val ! 文字列を実数へ変換
QRound = val
return
End Function QRound
追記:
こういう書き方もありますね。こっちの方が、3倍は速い。(呼び出し回数が少ないので、全体でみると、ほぼ同じなんですがね)
DOUBLE PRECISION Function QRound2(val)
DOUBLE PRECISION val
Qround2 = aint( val * 10000.0) / 10000.0
End Function QRound2