什麼是位運算?
C++提供了6種位運算符來進行位運算操作:
& 按位與
| 按位或
^ 按位異或
~ 按位取反
<< 左移(左邊消失,右邊補0)
>> 右移(右邊消失,左邊補符號位)
位運算的操作數是整數類型或字符型.
按位與&運算
110
& 運算常常用來將某變量的某些位清0,而保留其它位不變。例如,需要將int型變量n的低8位全置成0,而其餘位不變,則用:
n = n & 0xFFFFFF00
& 也常用於二進制取位操作,例如一個數 & 1的結果就是取二進制的最末位。如果要判斷n的第8位(從右往左,從1開始數)是否是1,則用:
if (n & 0x80 == 0x80) 語句
附註:int型是32個二進制位,16進制整數每個數字代表4個二進制位,故16進制int型常量最多是8位。
按位或|運算
110
按位異或^運算
^運算通常用於對二進制的特定一位進行取反操作.例如n^0xff就使得n的最後8位取反。
110
^運算的特點是:如果a^b==c,則有a^c==b和c^b==a
^可用於簡單加密,參見顧森BLOG。
左移<<運算
通常認爲a << 1比a * 2更快,因爲前者是更底層一些的操作。因此程序中乘以2的操作請儘量用左移一位來代替。
定義常量時可以用<<運算。你可以方便地用(1 << 16) - 1來表示65535。很多算法和數據結構要求數據規模必須是2的冪,此時可以用<<來定義MAXN等常量。
右移>>運算
當a是正整數時,a>>b等價於a/(2的b次方)
當a是負整數時,a>>b並不等價與a/(2的b次方),而是等於a/(2的b次方)上取整。
如a=-9
cout<<a/2; //輸出-4.
cout<<(a>>1); //輸出-5.
我們也經常用>> 1來代替div 2,比如二分查找、堆的插入操作等等。
用>>代替除法運算可以使程序效率大大提高。最大公約數的二進制算法用除以2操作來代替慢得出奇的%運算,效率可以提高60%。
二進制求最大公約數原理。
若a<b gcd(a,b)=gcd(b,a)
若a、b都是偶數,則gcd(a,b)=2*gcd(a/2,b/2)
若a是奇數、b是偶數,則gcd(a,b)=gcd(a,b/2)
若a、b都是奇數,則gcd(a,b)=gcd((a-b)/2,b)
位運算的簡單應用
整數類型的儲存
換言之,~a+1 = -a,那麼a & -a得到什麼?
得到a的右數第1位爲1的數,這個操作可用來枚舉a中爲1的位,這在位操作中有較多應用。