ビット操作


ビット操作


ビット操作は様々な問題で使用される.時々、質問は明示的にビット操作を要求します.他の回、それは単にあなたのコードを最適化するための便利なテクニックです.

ビット事実とトリック


OR


x | 0s = x
x | 1s = 1
x | x = x

AND


x & 0s = 0
x & 1s = x
x & x = x

XOR


x ^ 0s = x
x ^ 1s = ~x
x ^ x = 0

二つの補数と負の数


コンピュータは、通常、2つの補数表現に整数を格納します.負の数がその絶対値の2つの補数として表される間、正の数はそれ自体として表されます(その符号ビットで1が負の数を示すために).
nビット数(nは符号ビットを除く数のビット数)の2つの補数は2^Nに対する数の補数である.
4ビットの数字を仮定し、-3を表します.-3に対する2^3の補数は5である.バイナリ5には101です.したがって、4ビット番号としての-3は、第1ビットが符号ビットである1101である.
すなわち、-KのNビット番号としての2進数表現はconcat(1, 2^(N-1) - K)である.
これを見るもう一つの方法は、正の表現のビットを反転し、1を追加することです.バイナリ3には011です.100を得るためにビットをフリップして、1を得るために101を加えて、それから1を得るために符号ビット1101を補充します.

論理積和シフト


一つのビットはストレージの基本単位で、1または0のいずれかを格納します.したがって、ビットが特定の型の値の左または右に移動すると、その値が変更されます.C言語の値のビット移動は、左または右シフト演算子を使用して実行されます.これらの演算子は、符号付きまたは符号なしの形式で整数データ型の変数の値の個々のビットで動作します.文字は内部的な整数であり、したがって、これらの演算子はそれらで動作します.
左シフト演算子は<<、右シフトは>>で表されます.これらの演算子はバイナリ演算子で、2つのオペランドを必要とします.

論理シフト


どちらの方向に符号なし整数で実行されるとき、シフトは論理的であると呼ばれています.論理シフトにおいて、どちらの側もシフトしている間、空きスロットはゼロで埋められる.
int main(void)
{
    unsigned int x = 8;
    unsigned int y = 8;

    x >>= 1;    // Right Shift by 1
    y <<= 1;    // Left  Shift by 1

    printf("After Right Shift, x = %d \n", x);
    printf("After Left  Shift, y = %d \n", y);
}
出力:
After Right Shift, x = 4 
After Left  Shift, y = 16 
値をnビットによって右にシフトさせる
  • は、N .
  • に上がる2のパワーによって、値を分割する効果を有する
    値をNビットによって左にシフトさせる
  • は、N .
  • に上がる2の力によって値を掛ける効果を有する

    算術シフト


    算術と論理左シフトは同じです.右シフトだけが異なり、それから負の値の場合のみです.したがって、サインされた値で正しいシフトをするプログラムは本質的に非移植性です.

    算術右シフト


    算術右シフトでは、値を右にシフトしますが、SIGビットの値で新しいビットを埋めます.
    連続して右シフトされていない番号で、我々は繰り返し、最も重要なビットのゼロをシフトしているので、0を取得します.サインされた否定的な数のために、我々が1つを最も重要なビットに移しているので、我々は-1を得ます.

    共通ビットタスク


    セットビット


    機能
    int SetBit(int Num, int BitIndex)
    {
        return num | (1 << BitIndex);
    }
    
    マクロ
    #define     SET_BIT(Num, BitIndex)      (Num |= (1 << BitIndex))
    

    クリアビット


    機能
    int ClearBit(int Num, int BitIndex)
    {
        int mask = ~(1 << BitIndex);
    
        return Num & mask;
    } 
    
    マクロ
    #define     CLR_BIT(Num, BitIndex)      (Num &= (~(1 << BitIndex)))
    
    MSBからビットインデックス(包括的)を持つすべてのビットをクリアするには、次の手順に従います.
    int ClearBitsMSBthroughBitIndex(int Num, int BitIndex)
    {
        int mask = (1 << BitIndex) - 1;
    
        return Num & mask;
    }
    
    ビットインデックスからLSB (全て)を通して全てのビットをクリアする
    int ClearBitsBitIndexthroughLSB(int Num, int BitIndex)
    {
        int mask = (-1 << (BitIndex + 1));
    
        return Num & mask;
    }
    

    ビットを得る


    機能
    int GetBit(int Num, int BitIndex)
    {
        return Num & (1 << BitIndex);
    }
    
    マクロ
    #define     GET_BIT(Num, BitIndex)      (Num &= (1 << BitIndex))
    

    トグルビット


    機能
    int ToggleBit(int Num, int BitIndex)
    {
        return Num ^ (1 << BitIndex);
    }
    
    マクロ
    #define     TGL_BIT(Num, BitIndex)      (Num ^= (1 << BitIndex))
    

    更新ビット


    i番目のビットを値に設定するには、まずその位置でビットをクリアし、意図した値をシフトします.
    機能
    int UpdateBit(int Num, int BitIndex, int Value)
    {
        int mask = ~(1 << BitIndex);
    
        Num &= mask;
    
        Num |= (Value << BitIndex);
    }
    
    マクロ
    #define     UPDATE_BIT(Num, BitIndex, Value)    ((Num = (Num & (~(1 << BitIndex)) | (Value << BitIndex))))