1. 程式人生 > >【持續更新】總結經典位運算Tricks

【持續更新】總結經典位運算Tricks

前言

  • 刷了幾個leetcode題,發現位運算的小trick還是挺多的
  • 加上之前面試也被問到有關位運算的問題,這裡總結一些關於位運算的小技巧
  • 這裡提醒一下,位運算的優先順序很低,不清楚的時候一定要加括號;尤其是&、|、^的優先順序比==等比較運算子還低,這個比較容易出錯

正文

(1) 取有符號整數的最後一個1,只保留該位為1,其它位為0

  • 這是樹狀陣列教會我的,各種位運算小題,我總是在這個基礎上瞎搞一搞
 int a = x & -x;
 //根據補碼的計算,我們知道它等價於如下形式
 int b = x & ~x + 1
;

(2) 取有符號數的最後一個0,只保留該位為1,其它位為0

  • 這個主要是在1的基礎上的修改
 int a = ~x & -~x;
 //簡化下形式(-~x = ~~x + 1 = x + 1)
 int b = ~x & x + 1;

(3) 找到一個有符號(或無符號)數的最後一個1,把該1設成0,其它位保持不變

  • 這個是我個人感覺非常常用的一個方法
  • 應用包括:判斷該數是否只有1(是否是二進位制數的整數次冪);dp時希望找到上一個二進位制位1比當前數少一個的數
 unsigned int a = x & x - 1;
 //第二種方法,只適用於有符號數,效率應該也沒有上面的高,不過記錄一下~
int b = x & -x ^ x;

(4) 判斷一個有符號(或無符號)數是否為2的整數次冪

  • 這是3裡提到的一個應用,本質就是看這個數是否只有一個二進位制1
if (x > 0 && (x & x - 1) == 0)
    return true;
else
    return false;