#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