あなたは、基本的なビット・コンピューティングのスキルを知っている必要があり(圧力DPなどを、検索エンジン最適化が使用されます)


A. ビットオペレーティング基礎

基本的なビット演算子はAND、OR、XOR、反転、左、右、次のように、これらの6つは、それらの動作のルールは以下のとおりです。


シンボル

説明

運用ルール 

2ビットが1であり、結果は1つだけです

|

若しくは

2つのビットが0であり、結果が0でした

^   

XOR

同一の2ビットは0、1つの異なっています

〜   否定 変数変数0 1,1 0
<< 低0.1 << N 2 ^ Nに等しいまで、廃棄各バイナリ全体左いくつかの上位ビット
>>

各バイナリいくつかのすべての権利は、符号なしで、0の上位ビット、符号付き数、コンパイラアプローチのそれぞれが異なる、いくつかの補数の符号ビット(右シフト算術)、いくつかの相補0(論理シフト) 。N >> N 2乗は、N / 2に等しいです。

注意:

1。6つの事業者では、否定だけ〜単項演算子で、他の5人は二項演算子です。

2。  整形データビット操作は、float型の、使用することができ、二重ビット演算は、コンパイラを説明します。


II。一般的なビット・オペレーティング・ヒント

単純なビット演算
1.「&」記号、X&Yは、バイナリAND演算における2つの小数であり、その小数点以下の値を戻します。(実施例3)=(10)(11)&2(10)2。
2.「|」記号で、x | yは、バイナリOR演算における2つの小数であり、その小数点以下の値を戻します。実施例3(11)| 2(10 )= 3(11)。
3.「^」記号は、X ^ Yは、バイナリ排他的論理和演算における2つの小数であり、その小数点以下の値を戻します。実施例3(11)、2(10)= 1(01)。
4「<<」記号、左シフト演算、<< X 2、Xはゼロで埋めバイナリ2つの右端、2×<< 4倍xの等価の各ビットの左側に移動します。
従って、「>>」の右シフト演算である、>> 1 xが除去最もつのXバイナリで、X / 2に相当します。


III。スキル概要

    整数を決定する奇数または偶数である:1及び位相の数、結果が偶数である結果が奇数で、0です。

    ビットnか否かを決定することは、1:X&(1 << n)は、結果が1である、記載されていない0です。

    N番目のビットが1に設定されている:Y = Xを|(1個の<< N)

    Y = Xの&〜(1個の<< N):Nは、最初のセット0であります

    ビットnの逆数の値:Y = X ^(1 << N)

    右端1~0:Y = X・(X-1)

    単離された右端の1:Y = Xの&(-x)

    |(X-1)Y = Xの1は、右端のビット1の背後に配置されています

    単離された右端0:Y =〜X&(X + 1)

    右端0~1:Y = Xの|(X + 1)

    1.整数が奇数または偶数である分析

    if ((x & 1) == 0) {
      x is even
    }
    else {
      x is odd
    }
    

    私は誰もがこの技術を見ているかなり確信しています。核となるアイデアは、最下位ビットb0が1の整数である場合、数が奇数であることです。バイナリ表現で、B0ビットのみが1又は0であることができる「X」からです。「X」とするAND演算他のビットb0の除去に加えて行ってもよいです。演算の結果が0である場合、B0は0であるため、その後、「X」は、偶数であり
    、又は「X」奇数です。

    いくつかの例を見てみましょう。我々は整数43を選択し、それが奇数であり、バイナリ表現であり、00101011それは、最下位ビットb0さ1(フォーカス)。そして、それは今、1つのフェーズになります。

        00101011
    &   00000001   (注释: 1 的二进制是 00000001)
        --------
        00000001
    

    そして、操作はそれを残しての高-B1-B7のB0を排除する方法を参照してください?結果は整数が奇数であることを教えてくれるれ、1です。

    今、私たちは、-43を見てください。負の2の補数2進数を得るための迅速な方法についてのヒントを1回数カウンタの絶対値をとることである(符号ビットは、正の先行ゼロは省略していることに注意)。だから、バイナリ-43である11010101、あなたはそれが最下位ビットが1で、その数が奇数であるまだ見ることができ、(黒板にノック:我々は補数を使用しない場合は、ケースではありません)。

    私たちは、それはバイナリコードです、98を見てください1100010

        01100010
    &   00000001
        --------
        00000000
    

    演算結果が98ビットb0が0であることを意味し、0になった後、それもあります。
    再び負、バイナリコードを試みる-98 10011110、B0ビットが0で、計算結果は、それがあっても-98であり、0です。

    2.ビットnが1であるかどうかを決定します

    if (x & (1<<n)) {
      n-th bit is set
    }
    else {
      n-th bit is not set
    }
    

    先端には、まず、Xを通るかどうか1&1を決定します。この技術は、それがいずれかのビットが1であるか否かを決定することができ、これが改善されています。その原理は、n 1ビット左シフトされた後、ビットn以外の他のビットを排除する所定数、とAND。

    以下は、結果の左側に、1:

    1         00000001    (same as 1<<0)
    1<<1      00000010
    1<<2      00000100
    1<<3      00001000
    1<<4      00010000
    1<<5      00100000
    1<<6      01000000
    1<<7      10000000
    

    我々は1「のX」およびnビット左シフトをAND演算した場合、それは効果的にnビットの他のビットに加えて、「X」排除することができます。演算の結果がゼロであれば、n番目のビットを示すこと0、そうでなければ1です。

    のは、いくつかの具体的な例を見てみましょう。

    第122は1?私たちの操作が実行されます:122 & (1<<3)
    122のバイナリコードであり011110101<<3結果は00001000

        01111010
    &   00001000
        --------
        00001000
    

    結果は3番目のビット122が1であり、0ではないことがわかります。

    注意:私の記事では、ビットは、0からカウントします。

    それを行う-33?これは、5番が1であるのか?

        11011111      (-33 in binary)
    &   00100000     (1<<5)
        --------
        00000000
    

    その結果、ビット1~5はない、0です。

    3番目のビットNが1に設定されています

    y = x | (1<<n)
    

    この技術はまた、上記のことを除いて、n番目の位置1へのシフト操作(1 << n)を使用する&と置き換えます|そして1にnビットの可変数は、第1または変数の操作位置の結果であり、nは1に設定されています。1ビットの結果またはフェーズ1();相または0のいずれかの数は、結果が0であるためです。これがどのように機能するか見てみましょう:

    私たちは120の数があると、それが第2の位置に望んでいます。

        01111000    (120 in binary)
    |   00000100    (1<<2)
        --------
        01111100
    

    -120 6位1それがあれば?

        10001000   (-120 in binary)
    |   01000000   (1<<6)
        --------
        11001000
    

    前記n個の第一は0で

    y = x & ~(1<<n)
    

    この技術の核心は、ということである~(1<<n)、そのビットnに加えて、他のビットが一つであり、0です。

    それは次のようになります。

    ~1        11111110  (same as ~(1<<0))
    ~(1<<1)   11111101
    ~(1<<2)   11111011
    ~(1<<3)   11110111
    ~(1<<4)   11101111
    ~(1<<5)   11011111
    ~(1<<6)   10111111
    ~(1<<7)   01111111
    

    n番目のビットがゼロに設定される、変数「X」「X」相の結果です。かかわらず、nビットの結果の数の0または1であり、0は0相です。

    これは一例であり、第4127が0に設定されてみましょう:

        01111111    (127 in binary)
    &   11101111    (~(1<<4))
        --------
        01101111
    

    前記nビットの値がネゲート

    y = x ^ (1<<n)
    

    この技術は、依然として「nビット値の設定」されているが、これは、変数「X」とXORされます。すべての二つの数が同じであれば、XOR結果は、人が1であるかどうか、0です。そして、それは、nビットがそれを否定作成する方法ですか?ビットnが1である場合、XORの結果は0〜1であり、ビットnがあれば逆に、0、1、次いでXOR演算結果は1です。それはしなかった、ビットが反転しています。

    次の例は01110101反転ビット5:

        01110101
    ^   00100000
        --------
        01010101
    

    他のビットと同じ場合は、しかし、第五は、0はその後のですか?

        01010101
    ^   00100000
        --------
        01110101
    

    気づきましたか?XORは2回行った最新値計算を返しています。パリティRAIDアレイと簡単な暗号計算を計算するために使用されるこの美しいXOR演算は、より多くの他の記事を参照してください。

    6右端0〜1

    y = x & (x-1)
    

    今、最終的にはもっと面白くなっ!5つのヒント少し退屈の前に真実を伝えるために。

    この技法は、0から1、右端になります。例えば、整数001010所与1 0(一番右の1を太字)、結果は00101000となります。それとも00010000それが唯一の1を持っているので、0に。

    ここではいくつかのより多くの例は以下のとおりです。

        01010111    (x)
    &   01010110    (x-1)
        --------
        01010110
    
        01011000    (x)
    &   01010111    (x-1)
        --------
        01010000
    
        10000000    (x = -128)
    &   01111111    (x-1 = 127 (with overflow))
        --------
        00000000
    
        11111111    (x = all bits 1)
    &   11111110    (x-1)
        --------
        11111110
    
        00000000    (x = no rightmost 1-bits)
    &   11111111    (x-1)
        --------
        00000000
    

    なぜそれができますか?

    よく見ると、上記の例を考える場合は、次の2つのケースがある見つけることができます。

    1. 存在の右に1から最もビット。この場合、減少は1ビットの値よりも低くなると、(あなたが元の値を得ることができるものを追加した場合に)自身が0になります。このステップは、一番右の1ブロックされており、それは元の値と演算となり、右端の1を0に設定しました。
    2. 1(全て0)は存在しないから右端のビット。この場合、マイナス値は、ビットがすべてのビット1,0及びその位相を設定され、結果がゼロでオーバーフローします。

    7. 1の単離され右端

    y = x & (-x)
    

    この技術は、右端の1見つけるために、他方は0に設定されています。例:01010100は00000100になります。

    ここではいくつかの例を示します。

        10111100  (x)
    &   01000100  (-x)
        --------
        00000100
    
        01110000  (x)
    &   10010000  (-x)
        --------
        00010000
    
        00000001  (x)
    &   11111111  (-x)
        --------
        00000001
    
        10000000  (x = -128)
    &   10000000  (-x = -128)
        --------
        10000000
    
        11111111  (x = all bits one)
    &   00000001  (-x)
        --------
        00000001
    
        00000000  (x = all bits 0, no rightmost 1-bit)
    &   00000000  (-x)
        --------
        00000000
    

    この技術は、2の補数を利用しています。、バイナリシステムを補完-x等しいです~x+1今、私たちは2つのシナリオを検討してみましょう:

    1. 右端のビットは、B(I 1)の存在です。我々は、すべてのビットは、2つの部分、ビットb(I-1)の右側にB(I)、Bに分割されます (I-2)、B(0)、 左ビットB(I + 1)、... 、B(nは)。今、私たちは計算-x:まずB、否定X(i)が0、B(I-1) 、...、bは(0) 1、および反転Bである(I + 1)、... 、B(N)。次に、B(I-1)、Bその後、実行プラス1 (I-2)、...、B(0)は0になり、B(I)1。最後に、元のX相は、Biがすべてゼロ(高い反転)を左、右にbiは1だけBI、全て0です。
    2. 右端の1は存在しません。0の値は、0の2の補数は、依然として0で0&0=0ないビットが1に設定されていません。

    8. 1は、右端のビット1の背後に配置されています

    y = x | (x-1)
    

    例:01010000は01011111になります。

    この手法は、0が1になりますので、完璧ではない、と0なし1。

        10111100  (x)
    |   10111011  (x-1)
        --------
        10111111
    
        01110111  (x)
    |   01110110  (x-1)
        --------
        01110111
    
        00000001  (x)
    |   00000000  (x-1)
        --------
        00000001
    
        10000000  (x = -128)
    |   01111111  (x-1 = 127)
        --------
        11111111
    
        11111111  (x = -1)
    |   11111110  (x-1 = -2)
        --------
        11111111
    
        00000000  (x)
    |   11111111  (x-1)
        --------
        11111111
    
    1. 1は存在しません。この場合x=0、およびx-1-1に等しいです。補数-1 11111111、位相0または1の結果が得られています。
    2. 1が存在します。、第六のヒントを参照するx-1ことが0に1を右端であろう、このビットおよび後続のビットがビット1に設定し、元の値または動作は、このビットは、ビット位置1の背後に設定される場合、それ以来そうでなければ、ビットは1であり、結果はOR演算であった、今0です。

    9. 0孤立右端の

    y = ~x & (x+1)
    

    この技術は、図7は、その値を1に設定し、他はゼロに設定され、右端の0を見つけ、対照的です。

        10111100  (x)
        --------
        01000011  (~x)
    &   10111101  (x+1)
        --------
        00000001
    
        01110111  (x)
        --------
        10001000  (~x)
    &   01111000  (x+1)
        --------
        00001000
    
        00000001  (x)
        --------
        11111110  (~x)
    &   00000010  (x+1)
        --------
        00000010
    
        10000000  (x = -128)
        --------
        01111111  (~x)
    &   10000001  (x+1)
        --------
        00000001
    
        11111111  (x = no rightmost 0-bit)
        --------
        00000000  (~x)
    &   00000000  (x+1)
        --------
        00000000
    
        00000000  (x)
        --------
        11111111  (~x)
    &   00000001  (x+1)
        --------
        00000001
    

    証明:0右端があるとします。~x右端の0 1に設定、x+1あまりにも。次いで、~x及びx+1ビットよりも高い相は、ビット0が設定されているよりも、X + 1ビット低い(反転するので、高い変更、および動作は、x + 1ハイ変更しない)0に設定されます下側の相比は、ゼロに設定されるように、このビットは、1に設定されています。

    10 0〜1の右端

    y = x | (x+1)
    

    例えば:1010 0011は10100111になります。

        10111100  (x)
    |   10111101  (x+1)
        --------
        10111101
    
        01110111  (x)
    |   01111000  (x+1)
        --------
        01111111
    
        00000001  (x)
    |   00000010  (x+1)
        --------
        00000011
    
        10000000  (x = -128)
    |   10000001  (x+1)
        --------
        10000001
    
        11111111  (x = no rightmost 0-bit)
    |   00000000  (x+1)
        --------
        11111111
    
        00000000  (x)
    |   00000001  (x+1)
        --------
        00000001
    

    証明:X及びX + 1相あるいは全く情報が失われます。0 X + 1右端が1となるように、結果は右端0権利です。または両方の相の結果max{x, x+1}、右端のX + 1 1 0に設定されています。

    おすすめ

    転載: www.cnblogs.com/jiangxin/p/11796707.html