浮動小数点型

浮動小数点のメリット

桁数の多い数字を少ない情報で表す事ができる!!

普段見慣れている「29.8125」などは「固定小数点」を用いて小数を表している。また、これを2進数で表すと「11101.1101」となる。 そのため、ぱっと見で分かるように扱う値の桁数が多い場合、その分使用するビット数が増えいてくのが容易に想像できる。

これを浮動小数点数を使用する事で少ないbit数で表現する事ができるようになる!

指数表記

「3.4 x 1038」の形で値を表す事を「指数表記」という。また、「3.4E+38」「3.4e+38」のように表す事を「E表記」とい う。

それぞれの値の意味は以下のようになる。

  • 3.4 ・・・仮数
  • 10 ・・・基数
  • 38・・・指数

また、仮数が整数1桁になるようにする事を「正規化」という。

このように指数表記は極端に大きいまたは小さい値だとしても、限られた枠内で表示が可能になる!

  • 固定小数点: 340,282,366,920,938,463,463,374,607,431,768,211,456 (39桁必要...)
  • 浮動小数点数: 3.4 x 1038 (3.4, 10, 38の3つが分かれば良い!)

使用できる枠が有限のコンピュータにおいて、桁数の多い数値を簡潔に表現できる指数表記が適しているのはイメージができるはず!

2進数と指数表記

コンピュータが解釈するのはバイナリーなので、指数表記を2進数で扱ってみる。ここでは先程の3.4 x 1038 を例に考えてみる。

10進数では桁上がりが10毎なので基数を「10」としていた。そのため、2進数だと桁上がりが「2」毎なので、基数を「2」とする。そのため、3.4 x 1038 は「1 x 2128」(近似)と表現できる。

よって、基数以外の仮数と指数を2進数で表現できれば良いので、仮数 1 と指数部128を2進数に変換するとそれぞれ「1」と「100,000,000」になる。これをビットとして保持できれば良いことになる!

float型

32bitで表され、10進数にして整数部と小数部合わせて約7桁分の値を保持できる。 自分の環境で下記のコードを実行した結果

  • 最小値: 1.17549e-38
  • 最大値: 3.40282e+38
  • 仮数部(2進数): 24桁
  • 桁数(10進数): 6
#include <iostream>
#include <limits>

using namespace std;

int main(){
    cout << "最小値" << numeric_limits<float>::min() << endl;
    cout << "最大値" << numeric_limits<float>::max() << endl;
    cout << "仮数部" << numeric_limits<float>::radix << "進数で"
         << numeric_limits<float>::digits << "桁\n";
    cout << "桁数" << numeric_limits<float>::digits10 << endl;

    return 0;
}

double型

64bit で表され、10 進数にして整数部と小数部合わせて約 15 桁分の値を保持できる。 自分の環境で下記のコードを実行した結果

  • 最小値: 2.22507e-308
  • 最大値: 1.79769e+308
  • 仮数部(2進数): 53桁
  • 桁数(10進数): 15桁
#include <iostream>
#include <limits>

using namespace std;

int main(){
    cout << "最小値" << numeric_limits<double>::min() << endl;
    cout << "最大値" << numeric_limits<double>::max() << endl;
    cout << "仮数部" << numeric_limits<double>::radix << "進数で"
         << numeric_limits<double>::digits << "桁\n";
    cout << "桁数" << numeric_limits<double>::digits10 << endl;

    return 0;
}