読者です 読者をやめる 読者になる 読者になる

MyEnigma

とあるエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

C++におけるビット演算

c++

プログラミング作法

プログラミング作法

  • 作者: ブライアンカーニハン,ロブパイク,Brian Kernighan,Rob Pike,福崎俊博
  • 出版社/メーカー: アスキー
  • 発売日: 2000/11
  • メディア: 単行本
  • 購入: 58人 クリック: 1,152回
  • この商品を含むブログ (205件) を見る

はじめに


C++を使っていると、結構ビットを使った処理が必要になります。

通信ソフトだと、ビットを使って状態などを表すと、

データ量を極限まで少なくすることができます。

また、リソースが限られている環境では、

ビット演算は計算コストが少ないので、

うまく利用することが計算コストを減らすことができます。


そこで、C++でよく自分が使用する

ビット処理系のメモを残しておきます。

進数変換

ビット処理をする場合、自分が一番使うツールが進数変換ツールです。

ある2進数のビットマスクを16進数に変換したりする時に使用します。

ExcelやMATLABなどでも進数変換はできますが、

自分の場合は下記のWebツールを使っています。

2進数、8進数、10進数、16進数相互変換ツール

シンプルですが、非常に早く立ち上げて結果を知ることができるので便利です。

Webツールですが、おそらくブラウザのjava scriptの機能のみを使用しているようなので、

ローカルにhtmlファイルを保存しておけば、オフラインでも使用できます。


または下記のような方法を使って、実際にC++のコードで進数変換するときもあります。

爆速でC++のプログラムを試せるようにする方法 - MY ENIGMA

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;
}


このプログラムを実行したの標準出力は下記の通りです。


参考資料

プログラミング作法

プログラミング作法

  • 作者: ブライアンカーニハン,ロブパイク,Brian Kernighan,Rob Pike,福崎俊博
  • 出版社/メーカー: アスキー
  • 発売日: 2000/11
  • メディア: 単行本
  • 購入: 58人 クリック: 1,152回
  • この商品を含むブログ (205件) を見る