目次
はじめに
C++を使っていると、結構ビットを使った処理が必要になります。
通信ソフトだと、ビットを使って状態などを表すと、
データ量を極限まで少なくすることができます。
また、リソースが限られている環境では、
ビット演算は計算コストが少ないので、
うまく利用することが計算コストを減らすことができます。
そこで、C++でよく自分が使用する
ビット処理系のメモを残しておきます。
進数変換
ビット処理をする場合、自分が一番使うツールが進数変換ツールです。
ある2進数のビットマスクを16進数に変換したりする時に使用します。
ExcelやMATLABなどでも進数変換はできますが、
自分の場合は下記のWebツールを使っています。
シンプルですが、非常に早く立ち上げて結果を知ることができるので便利です。
Webツールですが、おそらくブラウザのjava scriptの機能のみを使用しているようなので、
ローカルにhtmlファイルを保存しておけば、オフラインでも使用できます。
または下記のような方法を使って、実際にC++のコードで進数変換するときもあります。
2進数の変数への入力
ある整数型の変数に2進数の値を入力したい時は、
下記のように0bを付けて代入するのが便利です。
(0bの後に0/1以外を指定すると、コンパイルエラーになるので安心です)
int bitMask=0b01010101;
0xを使うと、16進数として指定できるので、
先ほどのツールを使用して2進数を16進数に変換したものを使用することもできます。
int bitMask=0x55;
ビット演算子
1. 論理和 OR :演算子 |
どちらかが1 ならば 1 、それ以外は0になります。
2. 論理積 AND :演算子 &
両方のビットが1 ならば 1 、それ以外は0になります。
3. 排他的論理和 XOR 演算子 ^
片方だけのビットが 1 ならば 1 、それ以外は0になります。
4. 否定 NOT 演算子 ~
各bitの0/1を反転する。
ビット処理における便利関数
上記のようにC++にはビット処理用の様々な機能がありますが、
ビット列を表示させたり、
ある一部分のビットを変更したり、取得したりする時に、
すこし不便です。
そんな時は下記のような関数を事前に準備しておくと、
ビット処理が非常に容易になると思います。
これらの関数は、冒頭のリンクの書籍を参考にしました。
具体的な使い方はmain関数を見ればわかると思います。
#include<iostream> using namespace std; /** * @brief 指定されたbitを1に変更する関数 * @param p 位置 (何ビット目か?) * @param[out] x 変数 */ void SetBit(int p, uint16_t *x){*x=(*x|(0x01<<p));} /** * @brief 位置pからn個のビットを取得する関数 * @param x 元となる変数 * @param p 位置 0スタート * @param n 個数 1スタート * @return 取得されたbit情報 */ uint16_t GetBits(uint16_t x,int p,int n){return ((x>>p)&~(~0x0000<<n));} /** * @brief bit列を表示する関数 * @param x 個数 1スタート * @return 取得されたbit情報 */ void ShowBits(uint16_t x){ int nbit=sizeof(x); for(int i=1;i<=nbit*8;i++){ printf("%x",GetBits(x,nbit*8-i,1)); //4bit境界でスペースを入れる if(i%4==0) printf(" "); } printf("\n"); } int main(){ cout<<"Hello world"<<endl; uint16_t a=0b0000000000000000; ShowBits(a); SetBit(3,&a); ShowBits(a); SetBit(5,&a); ShowBits(a); uint16_t b=GetBits(a,4,4); ShowBits(b); return 0; }
このプログラムを実行したの標準出力は下記の通りです。