#pragma twice

KAB-studio > プログラミング > #pragma twice > 228 Version 12.05 double の中身・指数部編

#pragma twice 228 Version 12.05 double の中身・指数部編

前のページへ 表紙・目次へ 次のページへ

 Version 12.05
double の中身・指数部編

では今回はたぶんかなり難しい、 double の中身について
う”〜
まず、前回の関数でいくつか試しに出力してみます

void Use_OutputDoubleBit()
{
    OutputDoubleBit( 1.0 );
    OutputDoubleBit( 0.1 );
    OutputDoubleBit( 0.5 );
}

00111111 11110000 00000000 00000000 00000000 00000000 00000000 
00000000 1.00000000000000000000

00111111 10111001 10011001 10011001 10011001 10011001 10011001 
10011010 0.10000000000000001000

00111111 11100000 00000000 00000000 00000000 00000000 00000000 
00000000 0.50000000000000000000

入りきらないから改行入れてあるからね
一番後ろのが元の値ね。それにしても……なんか法則性全然ないね。
1.0 と 0.1 って似そうなのに全然違う
特に 0.1 はね。この辺が誤差が出る理由
やっぱり難しそう……
だから、ひとつひとつ見ていくね。まず、一番左側のビットについて。こ
れは符号で、プラスだと 0 、マイナスだと 1 になります

    OutputDoubleBit(  1.0 );
    OutputDoubleBit( -1.0 );

00111111 11110000 00000000 00000000 00000000 00000000 00000000 
00000000 1.00000000000000000000
10111111 11110000 00000000 00000000 00000000 00000000 00000000 
00000000 -1.00000000000000000000

これはわかりやすいね
これはね
う”
次に double の中で一番シンプルな数、 2.0 について見てみます

    OutputDoubleBit( 2.0 );

01000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 2.00000000000000000000

うわ、ホントだ。ほとんどゼロ! でも 2 が一番シンプルってどういう
こと? かなり変すぎ
 2 が一番シンプルなのは、浮動小数点は 2 が基本になってるから。まず
は、この 2.0 を使って指数部について見てみます
指数部って、 10 をいくつ掛けるかってゆーのだったよね
そう……なんだけど、実際には 10 じゃなくて、 2 なんです
 2 ……?
上の 2.0 のを例に、指数部の部分を見てみます

 _______ ____
01000000 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 2.00000000000000000000

 _ が付いてる部分が指数部。つまり、 2.0 の指数部は

1000000 0000

ってこと
これが 2 を…… 1 個掛けてるってこと?
そう、これが 2 を 1 個掛けてる場合。だから 2.0 。でも……もうひと
つ 2 を掛けて 4.0 の場合はこうなります

 _______ ____
01000000 00010000 00000000 00000000 00000000 00000000 00000000 
00000000  4.00000000000000000000

あ、想像と違った……
きっとそうだと思った。この場合の指数部は

1000000 0001

ってなります。同じく 8.0 の場合は

 _______ ____
01000000 00100000 00000000 00000000 00000000 00000000 00000000 
00000000  8.00000000000000000000

 16.0 の場合は

 _______ ____
01000000 00110000 00000000 00000000 00000000 00000000 00000000 
00000000 16.00000000000000000000

って、これって int とかと同じ数え方じゃない!
そう、まとめると

1000000 0000 :  2.0
1000000 0001 :  4.0
1000000 0010 :  8.0
1000000 0011 : 16.0

つまり、 2 を何個掛けるか、が int とかと同じ方法で入ってるわけね
だいたい合ってるかな
だいたい?
最初の 1 はなんだと思う?
 int だと、最初の 1 ってマイナスって意味だったよね、でもなんか違う
し……
これは、 1.0 、 0.5 、 0.25 を見ればわかると思うよ

 _______ ____
00111111 11110000 00000000 00000000 00000000 00000000 00000000 
00000000 1.00000000000000000000

 _______ ____
00111111 11100000 00000000 00000000 00000000 00000000 00000000 
00000000 0.50000000000000000000

 _______ ____
00111111 11010000 00000000 00000000 00000000 00000000 00000000 
00000000 0.25000000000000000000

これをさっきのとまとめると次のようになります

0111111 1101 :  0.25
0111111 1110 :  0.5
0111111 1111 :  1.0
1000000 0000 :  2.0
1000000 0001 :  4.0
1000000 0010 :  8.0
1000000 0011 : 16.0

あ、普通に増えてるだけ…… unsigned ってことね。でも……
 2.0 を 2 で割ったら?
 1.0 ……それを 2 で割ったら 0.5 、 0.5 を 2 で割ったら 0.25 !
そういうこと。もう少し正確に書くと

...
0111111 1101 :  2 の -2 乗
0111111 1110 :  2 の -1 乗
0111111 1111 :  2 の  0 乗
1000000 0000 :  2 の  1 乗
1000000 0001 :  2 の  2 乗
1000000 0010 :  2 の  3 乗
1000000 0011 :  2 の  4 乗
...

ってなります
そういえば 2 の 0 乗は 1 だったね
だから、ビット的に一番大きいのと小さいのを見てみると、こうなりま


0000000 0000 :  2 の -1023 乗
...
0111111 1101 :  2 の -2 乗
0111111 1110 :  2 の -1 乗
0111111 1111 :  2 の  0 乗
1000000 0000 :  2 の  1 乗
1000000 0001 :  2 の  2 乗
1000000 0010 :  2 の  3 乗
1000000 0011 :  2 の  4 乗
...
1111111 1111 :  2 の  1023 乗

うわ、すごい大きな数……
 2 の 1023 乗だと、10進数で 0 が 300 個強付くくらいの数
うわ……
だから、浮動小数点なら桁そのものについてはそれほど気にしなくていい
かな
 int の比じゃないわね。でも……そういう大きな桁だと、誤差が出ちゃ
うわけよね
ううん、今見たように 2 の乗数は絶対に誤差は出ないから
あ、そっか、 2 をいくつ掛けるかってだけだから、誤差とか出ないん
だ。それに 0.5 とか 0.25 とか、 2 で割っていく数も誤差は出ないね
そういうこと。というわけでまとめ

・最初のビットはプラス/マイナスのフラグ。

・2番目のビットから12番目のビットは指数。
 2 の何乗か、を表している。
 unsigned int に近い形式で表現。
 ただし最初から 1023 が足された状態。

・ 2 の乗数の数は誤差が出ない。
 ... 0.125 0.25 0.5 1 2 4 8 16 ...

こんなところかな
じゃ、次回は仮数部の話ね!

/*
    Preview Next Story!
*/
……なんか今日のだけだとそんな難しくないけど
ひとつずつ追っていけばね
いっぱい出てくるとわかんなくなる?
というより、ビットの並びを頭の中で数値に変換するとかすると
げ、それは難しそう
特に仮数部の計算は難しいよー
げげ!
というわけで次回
< Version 12.06 double の中身・仮数部編 >
につづく!
って言っても、頭の中で変換、なんてまず必要ないんだけど
……勉強する意味ないし
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。