1. 程式人生 > 其它 >C語言高效位運算的妙用

C語言高效位運算的妙用

技術標籤:c++演算法

高效位運算的妙用

文章目錄

引言

計算機的儲存器是採用二進位制表示資料,直接用位運算直接處理記憶體,可以高效處理問題,提高問題解決的效率。

位運算子

位運算子有&(按位與),|(按位或),^(按位或與),<<(左移),>>(右移),~(按位取反)

二進位制補碼運算公式

-x = ~x + 1 = ~(x-1)
~x = -x-1
-(~x) = x+1
~(-x) = x-1

x+y = x - ~y - 1 = (x|y)+(x&y)
x-y = x + ~y + 1 = (x|y)-(x&y)
x^y = (x|y)-(x&y)
x|y = (x&~y)+y
x&y = (x|y)-x
x==y: ~(x-y|y-x)
x!=y: x-y|y-x
x< y: (x-y)((xy)&((x-y)^x))
x<=y: (x|y)&((x^y)|(y-x))
x< y: (x&y)|((x|y)&(x-y))//無符號x,y比較
x<=y: (x|y)&((x^y)|
(y-x))//無符號x,y比較

應用

乘法

對於一個整數,左移一位相當於乘以2;右移一位相當除以2;

求餘數

位運算可以求2的冪的餘數,示例如下

#include<iostream>
using namespace std;
int main(){
    int a,b;
    while(cin>>a&&cin>>b){
        cout<<(a&(b-1))<<" "<<a%b;
    }
}

執行結果
在這裡插入圖片描述

求餘數時形式為a&(b-1)

判斷奇偶性

判斷一個整數是奇數還是偶數,常規方法為a%2。這裡我們可以用上面介紹的求餘數的方法,即用a&1來判斷

相反數

x的相反數為~x+1

求整數的絕對值

這裡有兩種形式

#include<iostream>
using namespace std;
int main(){
   int x;
   while(cin>>x){
       int y=x>>31;
       cout<<(x^y)-y<<" "<<((x+y)^y)<<" "<<abs(x);
   }
}

執行結果
在這裡插入圖片描述

交換整數

void swap(int x , int y)
{
    x ^= y;
    y ^= x;
    x ^= y;
}

判斷一個數是否是2的冪

這裡我們用的是上面求餘數的方法,判斷的表示式為:
((x&(x-1))==0)&&(x!=0)

求平均數

對於兩個整數x,y,如果用 (x+y)/2 求平均值,這樣有風險,因為可能會產生溢位,x+y 可能會大於INT_MAX,但是我們知道它們的平均值是肯定不會溢位的,平均值我們可以這樣表示
((x&y)+(x^y))>>1

掩碼

  • 取int型變數a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
  • 將int型變數a的第k位清0,即a=a&~(1<<k)
  • 將int型變數a的第k位置1, 即a=a|(1<<k)
  • int型變數迴圈左移k次,即a=a<<k|a>>16-k (設sizeof(int)=16)
  • int型變數a迴圈右移k次,即a=a>>k|a<<16-k (設sizeof(int)=16)

集合的表示

並集 A|B
交集 A&B
差 A&(~(A&B))
包含 A|B==B
補集 ~A
屬於 1<<(x-1)&A ==1<<(x-1)
空集 A ==0