• ベストアンサー

不定値の出力について

#include <stdio.h> int main(void) { /*  */ int x=1, a; /*  */ double y=0, b; /*  */ printf("a = %d\n", a); /*  */ printf("b = %f\n", b); /*  */ printf("x/y = %f\n", x/y); /*  */ printf("y/y = %f\n", y/y); /*  */ return(0); } -------------------------------------------------- このようなプログラムを実行すると、どのような出力結果が期待できるのでしょうか。 int 型と double 型しか用いていませんが、型によって説明が異なるのであれば他の型についても回答お願い致します。 コンパイラや環境によって出力結果が異なるのでしょうか。 具体的な出力結果でなく、どのように処理されるためにどのような出力が期待されるという形でも説明を頂けますでしょうか。 Visual C++ で実行した結果は次のようになりました。 -------------------------------------------------- a = -858993460 b = -92559631349317831000000000000000000000000000000000000000000000.000000 x/y = 1.#INF00 y/y = -1.#IND00 -------------------------------------------------- ご教示いただければ幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
  • chirubou
  • ベストアンサー率37% (189/502)
回答No.2

x/y が INF となったのは y が 0.0、つまりゼロで割ったために「無限大」になったことを示しており、y/y はゼロをゼロで割ったために「不定」という(特殊な)値になったことを示しています。これらはそういう定義(仕様)です。これらの詳しい(詳し過ぎる?)説明は URL を参考にしてください。 初期化されていないメモリの値は、その物理メモリが OS やそれ以前に動いていたプログラムが書いた値がそのまま残っていて、その値が「たまたま」取れて来ただけです。ゼロに初期化しない理由は、単に歴史的な経緯というだけです。 値は以前に動いたプログラムの(なんらかの)値なのですが、前にこれこれのプログラムを動かしたから常にこの値になるはずだ、ということは「たまたま」そうなることはあっても、常に正しいとは限りません。

参考URL:
http://docs.sun.com/source/806-4847/ncg_goldberg.html#1113
quads
質問者

お礼

参考ページまでありがとうございます。拝見させていただきました。 無限大に関してはNaNが生じる場合に、ある条件の下での極限として定義されていることで便宜的に処理できるのですね。 概ね説明に十分な理解ができました。 回答ありがとうございます。

その他の回答 (2)

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.3

まずこの結果をみていえるのは貴方はデバッグ情報付でコンパイルしていますね? このあたりがどういう結果になるかははVisual C++のバージョンによってちがいますが 最新の2005の場合は実行中で警告がでます。(初期化されていないという警告) -858993460 この値ですが 16進数では0xCCCCCCCC です。(Winの関数電卓で16進数にしてDWORDを選択すればわかります。) Visual C++のデバッグ版はデバッグしよすいように初期化されていない変数には意図的にCCが入りられます。 (デバッグ情報自体は別に存在して意図的にCCを入れた場合に警告はでません。) またリリース版でもどういう値が入るかはコンパイラの種類やコンパイルの最適化等の設定によって 変わってきます。 そのあたりを調べたいなら実行コードをアセンブラに置き換えてみていくと良いでしょう。 (VisualC++には逆アセンブル機能がついていると思います。)

quads
質問者

お礼

こちらの確認環境に関する情報に不備があり恐縮です。 詳しくないので提示する程度が分からず質問のような形になってしまいました。 > -858993460 > この値ですが > 16進数では0xCCCCCCCC > です。(Winの関数電卓で16進数にしてDWORDを選択すればわかります。) > Visual C++のデバッグ版はデバッグしよすいように初期化されていない変数には意図的にCCが入りられます。 > (デバッグ情報自体は別に存在して意図的にCCを入れた場合に警告はでません。) なるほど。こうした回答も大変参考になります。 回答ありがとうございます。 アセンブラでの確認ついても頭に入れておこうと思います。 このお礼を借りて失礼しますが、質問に対する回答をいただけたので、 これ以上回答が付かないようであれば締め切りたいと思います。 お二方ご回答ありがとうございました。

  • chirubou
  • ベストアンサー率37% (189/502)
回答No.1

不定値、というか初期化されていない自動(スタック)変数の値に、なにも期待できない、というのが仕様です。実際の値は、処理形や、直前に動かしたプログラム、OS などなど、様々な影響が考えられます。 ということで、気持ちは分からないでもないですが、決してこの値を仮定したプログラムを書いてはいけません。というより、動いたり動かなかったりして、バグ取りが大変になるだけです。

quads
質問者

お礼

回答ありがとうございます。 補足も入りますが、お礼として返答させていただきます。 今回質問させて頂いたのは、このような不適切な値(未初期化、不定)を参照した場合に、(質問で示したような)ある出力がされるのはなぜか? という疑問に対する回答(説明)を考察したかったためです。 何らかのアルゴリズムを実装する上で、これらの処理を用いることは考えておりません。 しかしながら、お気遣いありがとうございます。 > 実際の値は、処理形や、直前に動かしたプログラム、OS などなど、様々な影響が考えられます。 私が求めていた回答は仰られるようなものなのですが、 後者の除算に関して出力されている「 1.#INF00 」「 -1.#IND00 」といった値(文字列)はどのような処理を経て現れたのか? という疑問に対するもう少し詳細な説明はできるのでしょうか…? 重ね重ね質問してしまい恐縮ですが、ご回答いただければ幸いです。