【C言語】浮動小数点数型データ(float、double)を理解しよう!
今回は浮動小数点数型(実数型)を扱う方法について学習していきましょう。基本的な「型」について学ぶのは、前々回の「整数型」、前回の「文字型」と、今回の「実数型」で最後になります。
浮動小数点数型とは、「小数点を含む数値」だと思ってもらえればいいです。
- 実数型データ(float、double)の理解
浮動小数点数の型
浮動小数点数の型「float」「double」
浮動小数点数の型は、下表のとおり「float」と「double」になります。
型名 | バイト数 | 構造 |
---|---|---|
float | 4 | 符号部1bit、指数部8bit、仮数部23bit |
double | 8 | 符号部1bit、指数部11bit、仮数部52bit |
ここで、「仮数部」と「指数部」について説明します。浮動小数点数の型は以下の様に表されます。
- float = (-1)符号× 1.仮数部 × 2指数部-127
- double = (-1)符号× 1.仮数部 × 2指数部-1023
この表現は「指数表記」と呼びます。指数表記は、少ないデータ(ビット数)で大きなデータを扱えることが特徴です。
例えば「2,000,000,000」(20億)というデータがあったとします。
10進数の場合、普通に表現するのであれば、「2」×1個と「0」×9個、合計10個の数値を必要とします。
一方、指数表記「仮数 × 10指数」で表現した場合、これは「2 × 109」、すなわち仮数部の「2」と指数部の「9」、2個の数値のみで表現できるわけです。この特徴は当然、2進数表記でも同様です。
上記踏まえた上で、floatとdoubleの構造を見てみましょう。doubleの方が表現範囲が広いんだということが分かると思います。
例えばfloatであれば、指数部8bit(0~255)ですから、2-127 ~ 2128まで表現できるということが分かるかと思います。10であれば大体38乗ぐらいですから、int型変数(4byte)の桁数である42億(10の9乗)よりはるかに大きな値が扱えることが分かりますね。ただし、仮数部は23bitしかないため、intの31bitより表現できる分解能は少ない、ということになります。
・・・ぐらいまでを理解できれば、開発で使う分には全く困りません。これ以上更に知りたいという方は、他の詳細に解説してあるページをご参照いただければと思います。
データの表現範囲
実は、float、doubleで表現できるデータの範囲は、上記で解説したbit数の範囲内以外であること以外に、環境における制約などがあり、一概には決められておらず、コンパイル環境によって決まります。
それらの範囲は「float.h」というファイルに定義されています。以下のコードを実行してみて、float、doubleの最小値、最大値を表示してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> #include <float.h> int main(void) { printf("%e <= floatの絶対値の範囲 <= %e\n", -FLT_MAX, FLT_MAX); printf("floatの浮動小数点の最小値 = %e\n\n", FLT_MIN); printf("%e <= doubleの絶対値の範囲 <= %e\n", -DBL_MAX, DBL_MAX); printf("doubleの浮動小数点の最小値 = %e\n\n", DBL_MIN); return 0; } |
実行結果で表示される値が、実際の表現範囲になります。大体上で書いた通りの範囲(10の38乗)になっているということが分かるかと思います。
-3.402823e+38 <= floatの絶対値の範囲 <= 3.402823e+38
floatの浮動小数点の最小値 = 1.175494e-38
-1.797693e+308 <= doubleの絶対値の範囲 <= 1.797693e+308
doubleの浮動小数点の最小値 = 2.225074e-308
使用例
それでは、浮動小数点数型の変数を使って演算してみましょう。結果を表示させる際に使用しているprintfのフォーマット指定子はfloatが「%f」、doubleが「%lf」(ロングフロート)になります。なんのこっちゃ?って方は、前のページをおさらいしてきましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <stdio.h> int main(void) { float f_data = 0.2; double d_data = 1.2345; f_data = f_data / 2.0; printf("f_data = %f\n", f_data); d_data = d_data * 1000000000000000.0; printf("d_data = %lf\n", d_data); return 0; } |
これは是非、ご自身で色々な値に変えてみて下さい。特にこういうことを試してみて下さい。
- オーバーフローするような数値(仮数部、指数部それぞれで試す)
- float、double同士の足し算、引き算
- int型変数との足し算、引き算
恐らく色々な発見があると思います。
ひとまずある程度の演算が出来れば、今は合格だと思います。ただし小数点型データを扱う際は「誤差」は避けては通れない壁になってきます。また別の記事にて、詳しく解説したいと思います。
まとめ
浮動小数点数(実数)の表現については理解できたでしょうか。整数型データ(short、int、long)と、今回の浮動小数点型データ(float、doublr)を使いこなせれば、数学的な演算はほとんどが出来る様になります。
次回は「配列」について説明したいと思います。お疲れ様でした。
ディスカッション
コメント一覧
まだ、コメントがありません