1. 程式人生 > 其它 >新知識-位運算(Leetcode 217_存在重複元素)

新知識-位運算(Leetcode 217_存在重複元素)

新知識-位運算

&、|、^、~、>>、<<

  • 計算機對二進位制位數進行的運算(+-*/),符號位共同參與運算。
  1. 按位與運算子(&)

    (*)兩個1才為1,出0則0;

    • 負數先進行補碼轉換再進行與運算

    • 清零:將某數清零,將其所有位數與0相與,結果為0;

    • 取指定位

      • 比如10110010想取其後四位,只需要將其與00001111相與,也就是說,將需要獲得的位數與1相與保留本身,將其他位與0想與,便可達到取位的作用.
      • 10110010 & 00001111 = 00000010
    • 判斷奇偶

      最末位為0為偶數,最末位為1為奇數

      • 因此可以用(if ( a & 1 == 0)) 取代 (if (a % 2 == 0 )).
  2. 按位或運算子(|)

    (+)兩個0才為0,出1則1;

    • 設1
      • 某些位設1 0010010 | 01100000 = 11110010
  3. 異或運算(^)

    相同為0,不相同為1;

    • 交換律、結合律、xx=0,x0=1、自反(abb=a^0=a)

    • 翻轉指定位 10111110 ^ 00001111 = 10110001

    • 與0相異或值不變

    • 交換2個數

      • void Swap(int &a, int &b){
            if (a != b){
                a ^= b;
                b ^= a;
                a ^= b;
            }
        }
        
  4. 取反運算子(~)

    0變1,1變0

    • 最低位變0

      a & ~1 = 10110001 & 11111110 = 10110000

  5. 左移右移運算子(<< >>)
    • 所有位數左移,高位丟,低位補0

      • 10110110 << 2 = 11011000

        左移時捨棄的高位不包含1,則每左移一位,相當於該數乘以2.

    • (>>) 所有位右移,無符號高位補0,有符號,各編譯器分為算數右移(補符號位)和邏輯右移(補0)

  • 不同長度的資料進行位運算:如果兩個不同長度的資料進行位運算時,系統會將二者按右端對齊,然後進行位運算。

    1. long與int相與 4個位元組、2個位元組,右邊對齊,當
      1. 整數資料為正時,左邊補16個0
      2. 為負,左邊補16個1
      3. 無符號,左邊補16個0

菜鳥教程學習打卡