- ベストアンサー
log(0)と-1.#INF00Pの関係
#include<stdio.h> #include<math.h> main() { double y; y=log(0); printf("%lf",y); return 0; } 上のプログラムを実行すると -1.#INF00P という結果が出力されます。 これは一体何なのでしょうか?値なのですか? http://www.okweb.ne.jp/kotaeru.php3?q=648430 ではlog(0)の影響で 1.#INF00 という結果になっているようですが、何が違うのでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>INFOOの後ろのOOがよく分からないですが…。 今BCC32でコンパイルしたところ"-INF"という表記でした 00は恐らく∞を、0を繋げて表現しているのだと思います。 ところでy = 1 / 0と y = 1.0 / 0.0では意味も結果も違います。 前者は1÷0をint型で行った後にdoubleにキャスト(変換)します。 結果1.0になります。 後者はdoubleで計算を行い結果がINFになります。 0で除算しようとして Unix系やWindowsの場合だと、実行中にエラーを返すことはありません。 コンパイラによってはErrorではなくWaningがでますが。 Errorがでるなら計算前に分母をチェックする必要がありますね。 >10の19乗は大丈夫ですが >10の20乗はエラーになりました。 Rossanaさんは型について意識しているでしょうか? doubleの有効数字はせいぜい16桁です。 それと y=exp(10000000000000000000);とした場合コンパイラは まず10000000000000000000をint型として認識しようとます。 10000000000000000000.0としてください。 それでも駄目なら1E+20としてください。 それでエラーは無くなると思います。 ちなみにBCC32では「10000000000000000000」でも問題ありませんでした。 #コンパイラは何を使っているのかと #OSの種類を書いたほうが適切なアドバイスが受けやすいかと思います。
その他の回答 (3)
- sha-girl
- ベストアンサー率52% (430/816)
>doubleの有効数字って具体的にはどういうことですか?? これは浮動小数点について知れば理解できます。 最初に書いたURLにも説明がでていますが浮動小数点は 符号、指数部、仮数部の情報が入っており double(8バイト)の中にその情報を押し込めています。 情報量はたかだか8バイトなのですから有効数字にも限界もあるわけです。 浮動小数点についてはこちらのURLの方がわかりやすいかもしれません。 http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text/fudo.htm >なぜ前者の結果は1を0で割っているのに1.0になるのですか? 理由については「ビット演算」を知る必要があります。 コンピュータは二進数で処理しますが 掛け算の場合 5 * 2 = ? 5は2進数で 101ですがこれを2倍するというのは左に1個ビットをずらす ことなのです。 左にずらすと1010となり10進数では10になります。 逆に2で割るというのは右にずらします。 で1ならそのままで、0の場合どうなるかですが この定義がされているかどうかは分かりませんが BCC32の場合は、なにもせず1になります。
お礼
回答ありがとうございました。 >ところでy = 1 / 0と y = 1.0 / 0.0では意味も結果も>違います。 >前者は1÷0をint型で行った後にdoubleにキャスト(変換)します。 >結果1.0になります。 >後者はdoubleで計算を行い結果がINFになります。 まとめると1(1.0)を0(0.0)で割ると, BCC32ではそのような結果になるけれど,VisualC++ではエラーになるということでいいでしょうか?
- neKo_deux
- ベストアンサー率44% (5541/12319)
-1.#INF00Pは「やたら小さい数」という値です。 「2.7182のX乗=0の時のXは?」という計算をやらせたようなもので、グラフなどを描くと分かりますが、 X= 1:2.7182 X= 0:1 X=-1:0.3679 X=-2:0.1353 ・ ・ とXが小さくなるほど、0に近づきます。 一応は数値なので、計算や比較が可能です。 double型の値に関しては、IEEE754という規定でそのフォーマット、値の意味が定められています。(厳密にではないところがミソですが…) -- > 1.#INF00 こちらは符号が正です。 1.0/0.0= のような計算を行うと出る事があります。 0割りで停止する処理系なんかもあったハズですが。
お礼
回答ありがとうございます。 >「2.7182のX乗=0の時のXは?」という計算をやら >せたようなもので、グラフなどを描くと分かります >が、 実験してみました。yを次のように変更すると ●y=exp(-1000000000000000000); →0.000000 ●y=exp(-10000000000000000000); →1.#INF00(なんで∞なの!?) ●y=exp(-100000000000000000000); →定数が大きすぎます。というエラー。 >一応は数値なので、計算や比較が可能です。 なるほど数値とみなせるんですね!! >1.0/0.0= >のような計算を行うと出る事があります。 > >0割りで停止する処理系なんかもあったハズですが。 >0割りで停止する処理系なんかもあったハズですが。 まさに僕の環境ではy=1.0/0.0に変更すると 「除算、剰余演算が 0 で行われています。」 という実行エラーになりました。
補足
みなさんにお詫びしなくてはなりません。 -1.#INF00Press any key to continue と結果表示されたため,誤認しました。正しくは -1.#INFOO でした。訂正お願いしますm(__)m ◇追加実験結果 y=exp(10000000000000000000); →1.#INFOO なるほど∞ですね。 y=exp(100000000000000000000); →定数が大きすぎます。 10の19乗は大丈夫ですが 10の20乗はエラーになりました。 この扱える値の境界も決まっている事でしょうか?
- sha-girl
- ベストアンサー率52% (430/816)
-1.#INF00Pはマイナス無限大を表します。 コンパイラによっては-INF等となったり かならずしも表記が決まってはいないようです。 -0.0で除算しても同じ結果になると思います。 doubleは倍精度浮動小数点ですが 以下のサイトが参考になるかと思います IEEE形式浮動小数点について http://www.cc.nao.ac.jp/vppman/HTML/japan/langFort/fvp07/fvp00050.htm
お礼
回答ありがとうございます。-∞なのですね。 おそらくINFINITYの略なのでしょうかね。INFOOの後ろのOOがよく分からないですが…。 表記は決まってないのですね。 >-0.0で除算しても同じ結果になると思います。 実験してみました。 y=-1/0に変更 →除算、剰余演算が 0 で行われています。というエラーになりました。
補足
みなさんにお詫びしなくてはなりません。 -1.#INF00Press any key to continue と結果表示されたため,誤認しました。正しくは -1.#INFOO でした。訂正お願いしますm(__)m
お礼
アドバイスありがとうございます。 >00は恐らく∞を、0を繋げて表現している なるほど~そうっぽい感じですね。 >前者は1÷0をint型で行った後にdoubleにキャスト(変 >換)します。 >結果1.0になります。 >後者はdoubleで計算を行い結果がINFになります。 なぜ前者の結果は1を0で割っているのに1.0になるのですか? BCC32ではINFの表示なのですね。 #コンパイラはVisual C++ 6.0 #OSはWindowsXP です.
補足
>0で除算しようとして >Unix系やWindowsの場合だと、実行中にエラーを返すことはありません。 でも僕のパソコンでは0で除算するとエラーになります。 >Rossanaさんは型について意識しているでしょうか? >doubleの有効数字はせいぜい16桁です。 型を意識するようにこれから気をつけようと思います。 doubleの有効数字って具体的にはどういうことですか?? sha-girlさんの言う通り y=exp(100000000000000000000.0);やy=exp(1E+20); →1.#INFOO の結果がでました。