- 締切済み
fortran
fortran に関して質問です。 expに関するものです。 自分の認識としては、 expはドメインエラーが無い(値にNaNを放り込まない限り) と考えています。 プログラムを走らせていたら、 -exp : OVERFLOW error と表示されました。 問題の箇所はexp(val3)で、valはreal8です。 val3の計算が仮にNaNだとすると、expのoverflowではなく、domain errorと表示されると思うので、val3はある値を有していると思っています。 val3の計算をした後に、 if(val3 .gt. 1.0d307) val3=1.0d307 if(val3 .lt. -1.0d307) val3=-1.0d307 if(abs(val3) .lt. 1.0d-307) val3=0.0d0 としているので、問題ないのでは・・と思ったのですが・・ overflowなので、va3=1.0d307で処理されたと考えるのが妥当で、そうすると、expが半端なく大きな値になる⇒overflowになった。と考えています。exp内はどのくらいの値までなら大丈夫なのでしょうか? 考え方に問題がある場合なども、遠慮なく言って下さい。自分のためになりますので・・
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- Tacosan
- ベストアンサー率23% (3656/15482)
「どんな関数か」の中には, 「どのような計算をするのか」だけではなく「どのような引数/返り値なのか」も含まれてるんだけど, そこは気付かなかったのね. まず, exp(x) = e^x なんだから, real8 で表現できる値の範囲がわかれば引数として許せる値の範囲は数式 1本で求まる. 「自分の PC がどこまで処理できるか」なんてのは試す必要すらない. 実験してもいいけど, それは「試す」ではなく「確かめる」でなければならない. そうでなければただのアホだ. 次に, exp は総称関数だから, real8 を引数にとる以上 exp(100) を考えても多分無意味で exp(100d0) を調べるべき.
- Tacosan
- ベストアンサー率23% (3656/15482)
val3 は real*8 なんだよなぁ. なんで exp(100) を考えたんだろ? ぶっちゃけた話, exp(x) がどんな関数か理解できていないのでは?
補足
わかってますよ。 2.71828のx乗ですよね。 自分のPCがどこまで処理できるか試しただけ!! 300⇒100⇒10って感じに調べた。 ただ10よりもっと上(<100)でもあるかもしれないが、面倒なので放置してます。
- Tacosan
- ベストアンサー率23% (3656/15482)
overflow を回避するだけなら, 引数の値を「適切な範囲」に制限すれば十分だね. で, 見た感じでは val3 の値を ±1.0d307 の間に入れようとしてるんだね. その範囲に制限すれば overflow を回避できると思った根拠は?
補足
根拠は・・・ val3がreal8だから。 ただ、先ほど見直しして、val3が10以上なら10とするようにしました。 exp(100)がinfinityでしたから。手探りで『10』の値を見つけました。
- qaz_qwerty_me
- ベストアンサー率19% (214/1115)
20年以上 Fortranから縁がないので検討違いかもしれませんが・・・ > if(val3 .gt. 1.0d307) val3=1.0d307 > if(val3 .lt. -1.0d307) val3=-1.0d307 > if(abs(val3) .lt. 1.0d-307) val3=0.0d0 比較したいのは指数部と思います。 指数部の比較なら、素直に関数で指数部を抜き出し、抜き出した指数部を >> if( EXP( val3 ) .ge. EXP( 1.0d307) ) *EXPで指数部を抜き出せる関数と仮定
補足
あ、僕の質問の仕方が悪かったのかもしれません。 qazさんの言うことと、僕が行っている処理は同じです。 expにval3を入れる前に処理をするか否かの違いだけです。 言葉足らずになるかもしれませんが、単刀直入に・・ overflow回避のために何をしたらいいのでしょうか?
補足
書きもれです。100.0d0は。 はい、数式一本で706.・・・ですね。 冷静なご意見有難う御座います。