このページでは、double
型や float
型で扱う浮動小数点を printf
で表示する際に、小数点以下の桁をたくさん表示する方法について解説します。
みなさんも、実数を浮動小数点数で扱う際には「誤差が発生する」ということはご存知ではないでしょうか?
そして、例えば 0.3
などの値は double
型や float
型で扱うことができず、誤差が生じて実際には 0.29999....
という値で扱われているということも聞いたことがあるのではないでしょうか?
でも本当にそんな誤差が発生しているのでしょうか?実際に試してみましょう!
例えば下記を実行すれば、printf
で x
に格納されている値が表示されます。0.3
が 0.29999....
で扱われているのであれば、ここで 0.29999....
と表示されるはずですよね!
double x;
x = 0.3;
printf("%f\n", x);
実際に私の環境で試してみた結果が下記になります。
0.300000
いや、やっぱり誤差なんて発生してないじゃん!
騙された!
って思っちゃいそうな結果ですよね。
実は、本当は x
に格納されている値は 0.3
ではなく 0.29999....
です。間違いなく誤差が発生しています。
それにも関わらず上記のように表示されているのは、printf
で表示する小数点以下の桁数が少ないからです。表示する桁数が少ないので、printf
で表示する際にも値が丸められ、0.300000
と表示されています。
つまり、変数に格納する際にも誤差が発生し、さらに printf
で表示する小数点以下の桁数が少ないと、表示する際にも誤差が発生することになります。もう意味がわからなくなりそうです…。
では、printf
で誤差を発生させずに表示するためにはどうすれば良いのかというと、これは「小数点以下の桁数をたくさん表示してやる」ことで実現することができます。
ということで、前置きが長くなってしまいましたが、その printf
で小数点以下の桁数をたくさん表示する方法について解説していきたいと思います。
変換指定の “精度” に大きな値を設定する
printf
で小数点以下の桁をたくさん表示する方法は「printf
に指定する変換指定の “精度” を大きな値に設定する」になります。
printf
関数では、第1引数に指定する文字列の中で %d
や %f
などの変換指定を記述してやれば、その部分に第2引数以降で指定する変数の値を表示することが可能です。
double
型や float
型の浮動小数点数を小数形式で表示する際には、下記のように %f
もしくは %Lf
を変換指定として指定するのが一般的だと思います(%Lf
の方が精度が高いです)。この際に表示される小数点以下の桁数は 6
桁となっています。
double x;
x = 0.3;
printf("%f", x);
この printf
で表示する小数点以下の桁数を、6
桁から別のものに変更するのが “精度” です。精度は下記のように、.
(ピリオド)の後ろに指定します。
%.精度f
例えば小数点以下の値を 10
桁表示したいのであれば、%.10f
を指定すれば良いことになります。
この “精度” には大きい値も指定可能で、例えば 100
なども指定することができ、これにより小数点以下の値を 100
桁分表示することも可能です(1000
なども可能でした)。
で、このページの最初にも挙げた “0.3
に対する誤差” であれば、例えばですが、下記のように “精度” を 32
などに設定して printf
を実行することで確認することができます。
double x;
x = 0.3;
printf("%.32f\n", x);
私の PC で上記のプログラムを実行した結果、次のように表示されました。
0.29999999999999998889776975374843
やっぱり誤差は発生していますね!
こんな感じで、表示する小数点以下の桁数を多くする方法を知っていると、誤差が発生していることを確認するときなどにも便利ですので是非覚えておいてください!
参考:デバッガーだと printf
なしで確認可能
参考情報です。
ここまで printf
で小数点以下の桁をたくさん表示する方法を解説してきましたが、VSCode などでデバッガーを使えば、ある程度の桁数であればステップ実行時に勝手に表示してくれるので実はこっちの方が便利です。
ステップ実行とは、プログラムを “1行ずつ停止させながら実行する” ことを言います
例えば下図の左側に x
の値として 0.29999....
が表示されていることが確認できると思います。
printf
をわざわざ仕込まなくても誤差が発生していることが瞬時に確認できて便利です!
誤差の確認だけでなく、プログラムを1行ずつ停止させながら変数の中身の変化を確認したりできるので、プログラムのデバッグにはもちろんのこと、プログラムの動作の理解を深める際にも非常に便利です!
特に MacOSX ユーザー向けになりますが、下記ページで VSCode へのデバッガーの導入方法を解説していますので、是非こちらも参考にしてください!
VSCodeでMacOSにC言語デバッグ環境を構築上記ページを参考にするかはともかくとして、プログラミングをするのであれば、ステップ実行ができる環境は絶対に整えておいた方が良いと思います!デバッグ時の効率が格段に向上します。
スポンサーリンク
まとめ
このページでは、printf
で小数点以下の桁をたくさん表示する方法について解説しました!
変換指定の “精度” に大きな値を設定することで、小数点以下の桁をたくさん表示することができます。
単に printf("%f", x)
などを実行した場合、表示される小数点以下の桁数は 6
桁のみなので、この printf
実行時に誤差が発生する可能性があります。
この表示される小数点以下の桁数を増やすことで、その printf
実行時に発生する誤差を減らすことができ、より正確な値を表示することができるようになります。
浮動小数点数を扱う場合は、誤差によってプログラムが思わぬ動作をすることがあります。その原因を掴むためにも、この誤差を把握することが大事です。
その際にはこのページで紹介した内容が役立つと思いますので、是非覚えておいてください!
オススメの参考書(PR)
C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!
まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。
- 参考書によって、解説の仕方は異なる
- 読み手によって、理解しやすい解説の仕方は異なる
ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?
それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。
なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。
特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。
もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!
入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。
https://daeudaeu.com/c_reference_book/