- ベストアンサー
なぜ最後の数値が出ませんか
- この質問では、プログラムの実行結果においてなぜ最後の数値が表示されないのかを説明しています。
- 問題のプログラムでは、特定の条件下で最後の数値が表示されない現象が発生しています。
- 質問者は、プログラムの挙動について不明点があり、その原因と解決策を知りたいと考えています。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
★『float』や『double』型は誤差に注意して下さい。 ・おそらく、0.900000 の次に 0.1 を加えると 1.000000001 となっていると思います。 つまり、内部では 0.100000001 という値が加算された状態になってしまい、比較すると 『1.000000001 <= 1.000000000』は『偽』となるために最後の『1.000000』の数値だけが 表示されなかったと思います。 原因: ・浮動小数点は『小数』以下を正しく表現できないのです。 理由は 2 進数で小数点以下も表現しようと無理やり(そいうルール)で小数を扱いますので 場合によっては正確にならないのです。 ・たとえば、『10÷3×3』は数学的には『10』に戻りますが、コンピュータの世界では誤差 から『9.99999998』などとなる場合があるのです。数学とはちょっと違います。 ・このため、『float』型や『double』型を利用する際には、誤差に注意してのプログラミング が必要になります。 ・今回は for 文の最後に『1.000000』が表示されるため、ここの部分を削除すると『0.900000』 までしか表示されなかったと思います。 余談: ・私は日本人ですが、いまだにちょっと文章がおかしい時があります。むかし、国語が苦手でしたので。 ・質問者さんは『外国人』のようですが、変換間違いもなく日常会話(文章)は問題はないと思います。 ・以上。おわり。→浮動小数点は『誤差』に注意して下さい。
その他の回答 (5)
- jacta
- ベストアンサー率26% (845/3158)
浮動小数点数は多くの場合、内部的には2進数を使っています。その結果、0.1という値は実際には0.1より少し大きな値として扱われます。ですから、a <= 1.0の部分で、11回目(1.0と等しくなることを期待している回)では、実際にはaは1.0より少し大きいために条件が偽になってしまいます。 また、float型からdouble型に変換する際にも誤差を増大させています。double型ではじめから0.1と記述するより、いったんfloat型の変数に格納してからdouble型に変換する方が、同じ0.1のつもりでもより大きくなります。 ところで、全然違う話ですが、main関数の返却値型はint型にすべきです。void型を許している処理系もありますが、その場合は使用されている処理系を特定しなければ、何が起こってもしかたがないという結論になります。 # ちなみに私が使っている処理系では、質問者さんのコードは警告が出ますし、コンパイルオプション次第ではエラーになります。
お礼
質問について細かく説明させてありがとうございました。
- sakusaker7
- ベストアンサー率62% (800/1280)
浮動小数点数を扱うときには、他の方も書かれているように 十分注意する必要があります。 特に == による比較などは行ってはいけません。 日本語ですが 浮動小数点演算について http://docs.sun.com/source/806-4847/ncg_goldberg.html という文書に、事細かに解説があります。 bradforyou さんの native languageが何かは わかりませんが、 日本語に翻訳される前の元の論文が What Every Computer Scientist Should Know About Floating-Point Arithmetic http://docs.sun.com/source/806-3568/ncg_goldberg.html で読めます。 参考になるとよいのですが。
お礼
質問について原理部分がいい勉強になりました。 日本語の部分についてもいいホームページを紹介させてあれがとうございます。 私は韓国人です。
- venzou
- ベストアンサー率71% (311/435)
#3です、プログラムに間違いがありました、訂正します。 #include<stdio.h> void main(void) { float a; for(a=0.0; a <= 1.0; a +=0.1) { printf("%18.15f\n",a); } printf("%18.15f\n",a); }
- venzou
- ベストアンサー率71% (311/435)
このブログラムを実行してください。原因がよく分かります。 #include<stdio.h> void main(void) { float a; for(a=0.0; a <= 1.0; a +=0.1) { printf("%1.15f\n",a); } printf("%1.15f\n",a); }
お礼
そのままでして確認できました。しかも二回も答えさせてありがとうございます。 でもなぜするかについての部分も私のとって大事な部分ですので すみません。でもいい勉強になりました。
- episteme_at_goo
- ベストアンサー率25% (9/36)
floatの演算には誤差があるために、0.1を10回加えても1.0にはなりません。 したがって a == 1.0 がTRUEになることはなく、 a <= 1.0 は a < 1.0 と同じ意味になってしまいます。
お礼
内容は簡単でしたが理解することも簡単に出来てうれしかったです。 でもいい質問を選ぶのが一つだけで残念でした。 でも答えありがとうございます。
お礼
本当にありがとうございます。 答えを見た時すごいだと思ってきました。 また私の日本語についての部分のお話もありがとうございます。