C/C++ 言語 2進数 16進数 入門
Copyright (C) 2014 by Nobuhide Tsuda

 

※ イラスト提供:かわいいフリー素材「いらすとや」様

2進数 16進数 とは

我々が日常生活で使用するのは10進数である。
なぜ10進数なのかというと、手の指が合計10本あるからではないかと言われている。 もし手の指が4本だったなら、8進数が使われていて、読者が2進数に混乱することももっと少なかったかもしれない。

コンピュータ内部では、通常2進数が使用される。何故かというと、10進数よりも2進数の方がコンピュータにとって扱いやすいからである。 なので、気がつかないかもしれないが、入出力の時に10進数←→2進数の変換が陰でこっそり行われているのだ。

コンピュータは 0 または 1 のデータを取り扱う。これを「ビット(bit)」と呼ぶ。
ひとつのビットだけでは、表現できる状態が2つしかない。

これでは状態数が少なすぎなので、通常は8個のビットをひとまとまりとして取り扱う。
これを「バイト(byte)」と呼ぶ。

1バイトで表現可能な範囲は、2進数で書けば 00000000 から 11111111 まで。
10進数で書けば 0 から 255 までとなる。

2進数で表記すると桁が多くなりすぎるので、2進数の4桁をひとまとまりにして、通常は16進数を用いる。
0から9までは通常の数を用い、10~15は 'A', 'B', 'C', 'D', 'E', 'F' を用いる。
小文字('a', 'b', 'c', 'd', 'e', 'f')で表記してもよい。

16進数1桁は4ビットに相当する。

 10進数  2進数  16進数 
000000
100011
200102
300113
401004
501015
601106
701117
810008
910019
101010A
111011B
121100C
131101D
141110E
151111F

Nビットの数値を16進数に変換すると、(Nが4の倍数であれば、)N/4桁の16進数で表記できる。

演習問題

  1. 10進数の100を、2進数、16進数に変換してみなさい
  2. 2進数の 01011010 を 10進数、16進数に変換してみなさい
  3. 32ビットの数値を16進数に変換すると何桁になるか?
  4. 4桁の16進数を2進数に変換すると何桁になるか?

C/C++ 言語での 2進数、16進数

C/C++ 言語による2進数表記

2014年現在では Visual Studio 2013 C/C++で2進数をソースコードを記述することはできない。

が、C++14 で 0b または 0B で2進数を表記できることが決まった。なので、VS2015 あたりでサポートされるはずだ。
clang は 3.2 から、gcc は 4.9 から対応(予定?)のようだ。

    //  C++14 で導入予定:
    int a = 0b1010;         //  2進数の 1010、すなわち10進数の 10 を a に代入

では、現状の C/C++ で、ソースコードに2進数を書きたい場合はどうしたいいのか?

諦めて16進数で記述するか、2進数文字列→数値変換関数をコールするという方法がある。

    int a = 0xa;       // 0xa = 0b1010
    int b = binToInt("1010");

※ binToInt() 関数の実装方法は後述する

Boost やテンプレート機能を駆使すると、C++11 でも、2進数リテラルを記述することは可能のようだ (参照:C++ で 2 進数を書く)。 が、初級者にはちょっとむずかしいかもしれないので、素直に C++14 を待つのがいいかもしれない。

C/C++ 言語による16進数表記

C/C++ 言語による2進数表示

C/C++ 言語による16進数表示

  • C/C++ の printf文で変数の値を10進数表示する場合は %d を使用する。
  •     int x = 100;
        printf("x = %d\n", x);        //    10進数表記
    

    実行結果:

    x = 100
    
  • C/C++ の printf文で変数の値を16進数表示する場合は %x を使用する。
  •     int x = 100;
        printf("x = 0x%x\n", x);        //    16進数表記
    

    実行結果:

    x = 0x64
    
  • 場合によっては、16進数を固定桁数にし、先頭に0を付けたい場合がある。
    そんな場合は %0桁数x を使うといいぞ。
  •     int x = 100;
        printf("x = 0x%04x\n", x);        //    16進数4桁表記
    

    実行結果:

    x = 0x0064
    
  • C++ の iostream の cout を使って変数の値を10進数表示する場合は << を使用する。
  • #include <iostream>     //    for std::cout
        .....
        int x = 100;
        std::cout << "x = " << x << "\n";        //    デフォルトは10進数表記
    

    実行結果:

    x = 100
    
  • C++ の iostream の cout を使って変数の値を16進数表示する場合は、<< std::hex を使用して、16進数モードに切り替える。
  • #include <iostream>     //    for std::cout
        .....
        int x = 100;
        std::cout << "x = 0x" << std::hex << x << "\n";        //    16進数表記に切り替え
    

    実行結果:

    x = 0x64
    

    ※ 一度16進数モードに切り替えると、その後も16進数表示される。
      10進数モードに切り替えるには << std::dec を記述する。

  • cout で桁数を指定するには <iomanip> をインクルードし、std::setw(wd) を使う。
    さらに、桁を埋める文字指定には std::setfill(c) を使う。
  • #include <iostream>     //    for std::cout
    #include <iomanip>      // for std::setw, std::setfill>
        ....
        int x = 100;
        std::cout << "x = 0x" << std::hex << std::setw(4)
                        << std::setfill('0') << x << "\n";
    

    実行結果:

    x = 0x0064
    
  • 正直言って、printf より cout が好きな筆者でもこの表記はめんどくさいと考える。
    下記のように、16進数出力のためのマクロを定義しておけばいいのではないだろうか?
  • #include <iostream>     //    for std::cout
    #include <iomanip>      // for std::setw, std::setfill>
    #define  hexformat(fill, wd)    std::hex<<std::setfill(fill)<<std::setw(wd)
        ....
        int x = 100;
        std::cout << "x = 0x" << hexformat('0', 4) << x << "\n";
    

    実行結果:

    x = 0x0064
    

C/C++ 言語による整数・2進数表記変換

C/C++ 言語による整数・16進数表記変換

参考


演習問題解答例