#1 変数を覗いてみよう
(3) (98年11月7日 初版)
1.3 2進数
0から20までの整数を2進数で表示するプログラムを示します。関数
dec2bin() は受け取った整数値のビットパターンを画面に出力します。
この関数 dec2bin() がなにを行っているかは後で明らかになります。
// dec2bin.cpp
// 整数のビットパターンを表示
#include <iostream.h>
#include <iomanip.h>
//10進数を2進数に変換してプリントする
void dec2bin(int dec)
{
int size = sizeof(int)*8;
for(int i= size -1; i >= 0; i--){
if( (dec >> i) & 1 )
cout << '1';
else
cout << '0';
if( i % 8 == 0 ) cout << " ";
}
cout << endl;
}
int main()
{
int dec = 0;
while(dec <= 20){ // 0から20まで
cout << setw(3) << dec << ": ";
dec2bin(dec);
dec++;
}
return 0;
} |
ソースファイル( dec2bin.cpp)
[実行結果]
0: 00000000 00000000 00000000 00000000
1: 00000000 00000000 00000000 00000001
2: 00000000 00000000 00000000 00000010
3: 00000000 00000000 00000000 00000011
4: 00000000 00000000 00000000 00000100
5: 00000000 00000000 00000000 00000101
6: 00000000 00000000 00000000 00000110
7: 00000000 00000000 00000000 00000111
8: 00000000 00000000 00000000 00001000
9: 00000000 00000000 00000000 00001001
10: 00000000 00000000 00000000 00001010
11: 00000000 00000000 00000000 00001011
12: 00000000 00000000 00000000 00001100
13: 00000000 00000000 00000000 00001101
14: 00000000 00000000 00000000 00001110
15: 00000000 00000000 00000000 00001111
16: 00000000 00000000 00000000 00010000
17: 00000000 00000000 00000000 00010001
18: 00000000 00000000 00000000 00010010
19: 00000000 00000000 00000000 00010011
20: 00000000 00000000 00000000 00010100 |
結果をみやすくするために、1バイトごとに空白を入れて表示してい
ます。int型は4バイトすなわち32個のビットの並びになっていて、
0〜20まで2進数で表示されていることをよく確かめてください。
次に、小数の場合を考えてみましょう。たとえば、10進数で0.1を2進数
で表すと、
0.1の2進数表現 = 0.0001100110011.............
という具合に、循環小数となります。無限に続きます。ところがコンピュー
タはこのような数を有限ケタの数として扱いますから、数値0.1を正確に表す
ことができません。浮動小数点数を使用した計算の回数が多くなると丸め誤
差(round-off error 四捨五入による誤差)が大きくなります。
[演習問題1.3] 0.1の2進数表現を筆算で求めなさい。 回答
具体的にみてみましょう。0.1を1000回加えてみます。
// lst01_03.cpp
// 計算誤差
// 0.1 + 0.1 + 0.1 + .....
#include <iostream.h>
int main()
{
float sum = 0.0;
cout << "0.1 を1000 回加えます\n";
for(int i = 0; i < 1000; i++) // 合計は100にならない
sum += 0.1;
cout << "合計: " << sum << endl;
return 0;
} |
[実行結果] ソースファイル
0.1 を1000 回加えます
合計: 99.999 |
同じような足し算の繰り返しでも、2の倍数や2で割り切れるような数なら
誤差が生じないのではないでしょうか。例えば、0.1ではなく1/16 = 2^-4と
して、1000ではなく1024 = 2^10 としてみましょう。
// lst01_04.cpp
// 計算誤差
// 1/16 + 1/16 + 1/16 + .....
#include <iostream.h>
int main()
{
float sum = 0.0;
cout << "1/16 を1024 回加えます\n"; // 2^(-4) * 2^(10) = 2^6 = 64
for(int i = 0; i < 1024; i++) // 合計は64
sum += 1.0 / 16.0;
cout << "合計: " << sum << endl;
return 0;
} |
ソースファイル
この場合、結果は64となります。このようなやり方は計算誤差をできるだけ小さく
するために、使われます。例えば定積分の計算のようにある区間を分割して和を求め
るときに、分割の数を2の倍数に選ぶといった方法をとります。
| 目次 | 前のページ
| 次のページ |
Copyright(c) 1998,1999 Yamada, K