#pragma twice

KAB-studio > プログラミング > #pragma twice > 229 Version 12.06 double の中身・仮数部編

#pragma twice 229 Version 12.06 double の中身・仮数部編

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

 Version 12.06
double の中身・仮数部編

というわけで、前回に続き double の中身について見てみます
前回は指数部を見たんだよね。 2 の何乗かってゆーの
そう、 double の指数部は 2 の乗数を表してました。でも言い換える
と、指数部では 2 の乗数しか表せないってこと。整数だけ見てみると

1
2
4
8
16
...

ってなるわけだけど、その間の数が表現できなきゃ意味ないでしょ
つまり、仮数部がその間を表してくれるってわけね
そういうこと。仮数部は、 1.0 を例に見てみると、次の _ と ^ が付い
てる部分が仮数部になります

             _________________________________________________
00111111 11110000 00000000 00000000 00000000 00000000 00000000 
00000000 1.00000000000000000000
^^^^^^^^

って、指数部の後ろ全部仮数部なんだ
そう。ただ、仮数部のビットは前から増えていくから、後ろの方はとりあ
えず省略して

             _____________
00111111 11110000 00000000 1.00000000000000000000

って書きます
そのくらいで十分なんだ
さて、では早速見ていきます。まず、一番わかりやすい、 2.0 と 3.0 、
4.0 について見てみます

             _____________
01000000 00000000 00000000 2.00000000000000000000
01000000 00001000 00000000 3.00000000000000000000
01000000 00010000 00000000 4.00000000000000000000

指数部は、 3.0 は 2.0 と同じで、仮数部が 1 ……
仮数部だけにするとこんな感じ

0000 00000000 2.00000000000000000000
1000 00000000 3.00000000000000000000
0000 00000000 4.00000000000000000000

やっぱ 3 だけ 1 ……
同じように、 4.0 から 8.0 まで見てみます

             _____________
01000000 00010000 00000000 4.00000000000000000000
01000000 00010100 00000000 5.00000000000000000000
01000000 00011000 00000000 6.00000000000000000000
01000000 00011100 00000000 7.00000000000000000000
01000000 00100000 00000000 8.00000000000000000000

指数部は、 5.0 から 7.0 までは 4.0 と同じで、仮数部は……
仮数部だけ抜き出すとこんな感じ

0000 00000000 4.00000000000000000000
0100 00000000 5.00000000000000000000
1000 00000000 6.00000000000000000000
1100 00000000 7.00000000000000000000
0000 00000000 8.00000000000000000000

法則性あるようなないような……
まず指数部からまとめるね。指数部は、前回見たように 2 の乗数ごとに
増えるけど、その〈次の乗数〉までは指数部は変わりません
 4.0 からは、 8.0 までは同じ指数ってことね
で、次に仮数部。まず最初に正確な計算方法から教えておくね。仮数部に
は、常に 1 が入ってると考えて
 1 ?
そう。だから

0000 00000000 2.00000000000000000000

の仮数部は全部 0 だけど、これには 1 が入ってるって考えて
 1 が隠れてるわけね
で、指数部と仮数部を組み合わせてちゃんとした数を作るときには

指数部 x 仮数部

ってします
って、掛けてるだけじゃん
まぁそうなんだけどね
 2.0 だと、指数は 2 、仮数部は 1 だから 2 ってわけね
そういうこと。前回見た例は全部仮数部が 0 で埋まってた、つまり仮数
部が 1 だから
指数部計算したらそのまま答えだってわけね
そういうこと。それじゃあ次、仮数部の一番左に 1 が付いた場合。例と
して 3.0 の仮数部を見てみます

1000 00000000 3.00000000000000000000

簡単に言うと、仮数部は左のビットから、2分の1、4分の1、8分の
1、16分の1……ってなっていて、ビットが立っていたらそれを足すんで


この 3.0 の例だとこうなります

1 + 1/2 = 1.5

一番左の 1 は、仮数部に隠れてる 1 
さっき言ってたのね
その次の 1/2 が、一番左に 1 が立ってるから足される数
2分の1ってこういうことね。で、これを指数部の 2 と掛けると 3 にな
るわけだ
そういうこと。同じく

1000 00000000 6.00000000000000000000

仮数部は同じだから 1.5 で、それに指数部の 4 を掛けて 6 ね
次は一桁増やします

1100 00000000 7.00000000000000000000

一番左のビットは2分の1、その次のビットは4分の1だから、仮数部は

1 + 1/2 + 1/4 = 1 + 0.5 + 0.25 = 1.75

これに指数部の 4 を掛けて 7 ね
そういうこと。同じく

0100 00000000 5.00000000000000000000

一番左のビットが 0 だから2分の1は足さないから

1 + 0 + 1/4 = 1 + 0 + 0.25 = 1.25

そっか、 0 だったらそこのは足さないってことね
そういうこと。で、これに指数部の 4 を掛けて
 5 ってわけね、なるほどねー
さて、ここまでは計算方法。ここからは考え方
考え方?
まず、仮数部のビットが全部 0 だったとき、仮数部の数は?
 1 が隠れてるから 1 でしょ
では、全部のビットが 1 だったら?
えっと、 1 + 1/2 + 1/4 + 1/8 + ... ってなってくよね
そう。そうやって足していくと 2 に限りなく近づきます。でも 2 にはな
りません
計算するとそーなるね……で?
つまり、仮数部は、 1 以上、 2 未満にしかなんないってこと
あ……仮数部をどんなに大きな数にしようとしても、分数しか足せないか

 2 は越えられないんです。これと指数部を組み合わせて考えてみると

指数部:2の乗数を表す
仮数部:1〜2の間の数を表す

つまり、指数部は2倍ずつのとびとびの数を表して、仮数部はそのとびと
びの間を埋めるってこと
……指数部だけだったときは、 2 の次が 4 で、その次が 8 だったの
が、仮数部も使うと 3 とか 5 とか 6 とか 7 とかが出せるようになった、
ってゆーこと?
そういうこと。指数部と仮数部は、こういう役割分担があるってことだ

指数部は大きく増やして、仮数部は小さく増やすのね
仮数部の小さく増やす、っていうのはちょっと違うかな。さっきの 2 か
ら 4 を見てみると

0000 00000000 2.00000000000000000000
1000 00000000 3.00000000000000000000
0000 00000000 4.00000000000000000000

ってなってるでしょ。これと 4 から 8 のを見比べてみて

0000 00000000 4.00000000000000000000
0100 00000000 5.00000000000000000000
1000 00000000 6.00000000000000000000
1100 00000000 7.00000000000000000000
0000 00000000 8.00000000000000000000

真ん中の仮数部、同じでしょ
あ……
こんなふうに、指数部が増えても必ず中央に来る数の仮数部はこれ。これ
は、 100... = 1.5 だから、これに指数部を掛けるとちょうど間の数になる
から
計算するとそうなるね
で、指数部が増えるとその間の数も増えるけど、その場合は1ビット右に
増えれば、さらに間の数を表せるから

んー、じゃあこれとも見比べてみて

0000 00000000 2.0000000
0100 00000000 2.5000000
1000 00000000 3.0000000
1100 00000000 3.5000000
0000 00000000 4.0000000

 2 から 4 まで 0.5 刻み……あ!  4 から 8 のと同じ!
そう、つまり仮数部の右のビットを使っていくことで、間の数を埋めてい
くことができるんです
 2 から 4 だと 0.5 きざみ、 4 から 8 だと 1 きざみ、でも……分けて
る数は同じ……
こうやって、仮数部は、指数部の間の数を分割する意味があるんです
桁を増やせばどんどん分けられる、ってことは 2 と 2.5 の間とか……
2.25 ?
そう、 1 ビット増やせばそうなるわけ

0000 00000000 2.0000000
0010 00000000 2.2500000
0100 00000000 2.50000000000000000000

じゃあビットを増やしていけばどんどんどんどん割れるんだ
そう、なんだけど、あくまで割れるのは半分ずつ。 2.25 、 2.125 、
って感じに
なんかざっくりだね。細かい小数無理っぽい
そう! だから、 0.1 は
……仮数部のビットをどんどん使っていっても、近づけるだけ……だから
誤差が出る!!
そういうこと。つまり 0.1 とかは仮数部の性質上正確には表せないんで

誤差の原因はそんなとこにあったのね……

/*
    Preview Next Story!
*/
うーん、ややこしいような、そうでもないような……
そうでもない?
あ、うん、しくみは複雑じゃないよね
考え方はそうかも
計算するのは大変だけど
でも、計算なんて滅多にしないけど
へ?
というわけで次回
< Version 12.07 浮動小数点のまとめ >
につづく!
だからって無駄ってわけじゃないからね
ホントに〜?
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。