Translate

2013/08/22

FORTRANで四捨五入


Binary Coded Decimal / pboyd04


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

0 件のコメント:

コメントを投稿