エンジニアは豆電球の夢を見るか

日々の学びを書き綴る。忘れてしまうから。

ビット演算の基礎とビット抽出

ビット演算子

  • 左辺と右辺の同じ位置にあるビットを比較する
演算子 記述例 意味 概要
& a = b & 0x01 ビットAND 両方のビットが「どちらも」1の場合だけ「1」を出力する
| a = b | 0x01 ビットOR 両方のビットの「どちらかが」1の場合だけ「1」を出力する
^ a = b ^ 0x01 ビットXOR 両方のビットの「どちらかが」異なる場合だけ「1」を出力する

ビット反転

演算子 記述例 意味 概要
~ a = ~a ビットNOT 右辺の値の各ビットに対して「1は0」に「0は1」にする

ビットシフト

演算子 記述例 意味 概要
<<= a = a << 2 左シフト
>>= a = a >> 2 右シフト
  1. ビット演算
  2. ビットフラグ
  3. ビットマスク

ビットフラグの作り方

16進数で2進数の1桁ずつの立っているビットフラグを作成、 2進数で1桁ずつ立てればいいので、2の倍数で数値を作っていく

int BIT_FLAG1   = 0x0001;  //  2進数 : (0000 0000 0000 0001)
int BIT_FLAG2   = 0x0002;  //  2進数 : (0000 0000 0000 0010)
int BIT_FLAG4   = 0x0004;  //  2進数 : (0000 0000 0000 0100)
int BIT_FLAG8   = 0x0008;  //  2進数 : (0000 0000 0000 1000)
int BIT_FLAG16  = 0x0010;  //  2進数 : (0000 0000 0001 0000)
int BIT_FLAG32  = 0x0020;  //  2進数 : (0000 0000 0010 0000)
int BIT_FLAG64  = 0x0040;  //  2進数 : (0000 0000 0100 0000)
int BIT_FLAG128 = 0x0080;  //  2進数 : (0000 0000 1000 0000)

変数にフラグを立てる

int flag = BIT_FLAG1 | BIT_FRAG4;   //  1つ目と3つ目にフラグを立てる
  • 2進数で表すと
(0000 0001) OR (0000 0100) = (0000 0101)

ビット演算のサンプル

//  2進数表示のためのメソッド
void printb(unsigned int v) {
  unsigned int mask = (int)1 << (sizeof(v) * CHAR_BIT - 1);
  do putchar(mask & v ? '1' : '0');
  while (mask >>= 1);
}

int main(int argc, const char * argv[]) {
    
    int BIT_FLAG1   = 0x0001;
    int BIT_FLAG2   = 0x0002;
    int BIT_FLAG4   = 0x0004;
    int BIT_FLAG8   = 0x0008;
    int BIT_FLAG16  = 0x0010;
    int BIT_FLAG32  = 0x0020;
    int BIT_FLAG64  = 0x0040;
    int BIT_FLAG128 = 0x0080;
    
    printf("=== OR演算 ===\n");
    int flag = BIT_FLAG1 | BIT_FLAG2;
    printb(BIT_FLAG1);
    printf("\n");
    printb(BIT_FLAG2);
    printf("\n");
    printb(flag);
    printf("\n");
  
    // === OR演算 ===
    // 00000000000000000000000000000001
    // 00000000000000000000000000000010
    // 00000000000000000000000000000011
  
    printf("=== AND演算 ===\n");
    int flag1 = BIT_FLAG1 & BIT_FLAG2;
    printb(BIT_FLAG1);
    printf("\n");
    printb(BIT_FLAG2);
    printf("\n");
    printb(flag1);
    printf("\n");
  
   // === AND演算 ===
   //  00000000000000000000000000000001
   //  00000000000000000000000000000010
   //  00000000000000000000000000000000
    
    printf("=== XOR演算 ===\n");
    int flag3 = BIT_FLAG1 & BIT_FLAG2;
    printb(BIT_FLAG1);
    printf("\n");
    printb(BIT_FLAG2);
    printf("\n");
    printb(flag3);
    printf("\n");
    
    // === XOR演算 ===
    // 00000000000000000000000000000001
    // 00000000000000000000000000000010
    // 00000000000000000000000000000011
  
    printf("=== NOT演算 ===\n");
    printb(BIT_FLAG1);
    printf("\n");
    BIT_FLAG1 = ~BIT_FLAG1;
    printb(BIT_FLAG1);
    printf("\n");
    
    // === NOT演算 ===
    // 00000000000000000000000000000001
    // 11111111111111111111111111111110
  
    return 0;
}

フラグの抽出

void main()
{
    int flag = ( BIT_FLAG_1 | BIT_FLAG_4 );

    bit_extractor(flag);
}

void bit_extractor( int flag )
{
    //  flag = 0000 0000 0000 0101

    if( ( flag & BIT_FLAG_1 ) == 1 )  // true
    { 
        funcA(); 
    }
    if( ( flag & BIT_FLAG_2 ) == 1 )  // false
    { 
        funcB();
    }
    if( ( flag & BIT_FLAG_4 ) == 1 )   // true
    {
        funcC();
    }
    if( ( flag & BIT_FLAG_8 ) == 1 )   // false
    {
        funcD();
    }
}