LoginSignup
6
8

More than 5 years have passed since last update.

数値の構造をおさらいしよう(float,double)

Last updated at Posted at 2015-07-08

doubleとfloat

doubleとfloatは次のように呼ばれています。

double(倍精度浮動小数点型)

float(浮動小数点型)

そもそも浮動小数点型ってなんでしたっけ。

浮動小数点型

符号部(正負) + 指数部(10^) + 仮数部(数値) から構成される数値です。

符号部 : 数値がマイナスかプラスかを示すための部分

指数部 : 数値の大きさを示す部分

仮数部 : 値を格納する部分

となっております。なので32bitといえども、保存できる値の領域は決まっておるわけであります。

floatとdoubleの違い

構成 符号部 指数部 仮数部
float 1bit 8bit 23bit
double 1bit 11bit 52bit

floatは32bit(4byte),doubleは64bit(8byte)となっております。
doubleでは倍精度ということでfloatの倍のサイズを持っていることがわかります。
つまりデータとしてはdoubleのほうが2倍大きいのです。

たとえばfloatではこのように32bitの値であっても値として使える部分が
23bitと限られており、24bit目に値を入れちゃったりすると変な挙動をすることがわかります。

例えばこんな実験をしてみましょう。
int(32bit)でどんどん2進数でのbitフラグを立てていきます。24bitまで

Test

    int target{0};

    for(int i = 0 ;i < 25;i++)
    {
        target |= 1 << i;
        printf("%d\n",target);
    }

    printf("%f\n",(float)target);

    return 0;

結果
1
3
7
15
31
63
127
255
511
1023
2047
4095
8191
16383
32767
65535
131071
262143
524287
1048575
2097151
4194303
8388607
16777215
33554431
33554432.000000 // !! 最後の値がfloatにした瞬間変わっている

となりました。最後のintのtargetの値は33554431でしたが、これをfloatにキャスト値が変わってしまってますよね。
これはどういうことでしょうか。2進数表示に変換してみましょう

2進数表示
1111111111111111111111111 // <= 33554431 (24桁目まで1)
10000000000000000000000000 // <= 33554432 (25桁目のみ1)

これはどういうことでしょうか。floatでは仮数部が23bit、つまり数値として扱えるのは23bitまでなので
もともと24bitまで値が入っているintの値をキャストすると値が溢れてしまったということです。
たしかにfloatが23bitまでしか扱えないことがわかりましたね。

なので大きな値や数値の多いいbitフラグを扱う時はdoubleで行うべきであることがわかります。
doubleなら52bitまで扱えますからね。その分データは倍になってしまいますが。

普段intで32bitまで数値が扱えている分、ふとしたときにこういうワナにはまってしまわぬよう、覚えておきましょう。

6
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8