プロが教える店舗&オフィスのセキュリティ対策術

fortranで以下のようなプログラムにてxに1.0^-6を代入し、
その中身を表示しました。
---------------------------------
program test

real(8) :: x = 1.0d-6

write(*,*) x
write(*,*) x * 1.0d6
write(*,*) int(x * 1.0d6)

end program test
---------------------------------

しかし、結果は以下のようになり、
0.999999999999999955^-6となってしまいます。
さらに、やっかいなことに10^6倍して
整数型に変換しても0と認識されてしまうのです。
----------------------------------
$ ./a.exe
9.99999999999999955E-007
1.00000000000000000
0
----------------------------------

変数の型も倍精度で宣言し、定数も倍精度(d付き)で
代入しているはずなのですが、なぜこのような現象が
起きるのでしょうか。
ご存知の方いましたら教えて頂けると助かります。

なお、コンパイルはgfortranで行っています。

A 回答 (2件)

fortranは使ったことがないのですが、これはプログラミング言語全般で一般的に見られる現象と思います。

すなわち、小数の値に誤差が出る原因はなにか?ということですね。

小数は、コンピュータでは完全に正しく表現できません。誰でも思いつくのが循環小数の存在です。例えば、10 / 3は、0.33333……ですが、コンピュータでは適当な桁で終わってしまいます。0.33333という具合ですね。これに3をかけると0.99999で、1には戻りません(まぁ、最近の言語では循環小数を認識しちゃんと1に戻るものもありますが、考え方として、ということです)。この問題は、誰でも理解できることと思います。

この問題が、2進数でも起こります。すべての数値は、コンピュータ内部では2進数として処理されています。やっかいなのは、2進数と10進数では微妙にその性質が異なる点です。2進数では、1を10のn乗で割った値は循環小数になるのです。1 / 10は10進数では0.1で割り切れますが、2進数では循環小数になり割りきれません。先の10 / 3と同様、適当なところで切り捨てられ、不正確な値として保管されます。このため、1 / 10の値に10をかけても0.99999……となり、1には戻らないのです。

この現象が、ご質問のケースでも内部で起こっているのだと思います。
    • good
    • 0
この回答へのお礼

な、なるほど!!
そういうことだったのですね!

非常に的確で丁寧なご説明ありがとうございます。
とてもすっきりしましたm(_ _)m

いやー、こんなに即答して頂けるとは、・・・すごいですね!!

お礼日時:2011/05/03 13:17

どんな精度を使おうとも、有限の桁で処理している限り、10進数⇔2進数の変換の際に誤差が生じます。



http://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95% …
の「精度」のところに簡単に書いてあります。
「浮動小数点 誤差」「浮動小数点 精度」といったキーワードで検索するとたくさん解説がみつかります。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
そうだったんですね、勉強不足でした。
本当にありがとうございましたm(_ _)m

お礼日時:2011/05/03 13:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!