C++位運算

C++位運算

總結一下C++中位運算的用法。

&(與運算)

舉例 11&3 = 3

    00001011
&   00000011
=   00000011
=   3

常用例子
我們判斷是否被2整除,一般寫成if(n%2==0),使用位運算符也可寫作if(n&1==0)

|(或運算)

舉例 11|3 = 11

    00001011
|   00000011
=   00001011
=   11

<<(向左位移)

<<向左移動n位,右邊自動補0.
舉例 11<<1=22

00001011 << 1
00010110 = 22

m*2^n = m<

>>(向右位移)

>>向右位移,左邊自動補0.
舉例 11>>1=5

00001011 >> 1
00000101 =  5

同理m/2^n = m>>n(m除以2的n次方相當於m右移n位)

^(異或運算符)

兩個相同的位變成0,不同的位變成1
舉例 11^3=8

    00001011
^   00000011
=   00001000
=   8

應用1: Given an array of integers, every element appearstwice except for one. Find that single one.
比如int i = {1,2,3,3,2,1,5},找去其中的5
解法:將數組i中的所有數字依次異或,最後剩下的就是隻出現了一次的數字。
應用2:不借助臨時變量,交換兩個變量的值

void swap(int &a,int &b)
{
  a ^= b;
  b ^= a;
  a ^= b;
}

分析一下

例如a=8,b=4
a=1000 b=0100
a=a^b  a=1100(表示了a和b差異位)
b=b^a  b=1000(用差異位與b異或還原了a,此時b就是a的原始值)
a=a^b  a=0100(用差異位與a,也就是現在的b異或還原了b,此時a就是b的原始值)

~(按位取反)

加法中的應用
**x-y=x+~y+1
~y=-y-1**
例如~11=-11-1=-12

求解二進制中1的個數

題目描述:輸入一個整數,求解二進制中1的個數,負數用補碼來表示。
解法:
1. 普通法:按位與1進行與運算,然後右移直到數字變成0,來求解1的個數。
2. 快速法:使用n&(n-1),不斷清除n最右邊的1,直到n爲0,與的次數就是1的個數。(爲什麼n &= (n – 1)能清除最右邊的1呢?因爲從二進制的角度講,n相當於在n - 1的最低位加上1。舉個例子,8(1000)= 7(0111)+ 1(0001),所以8 & 7 = (1000)&(0111)= 0(0000),清除了8最右邊的1(其實就是最高位的1,因爲8的二進制中只有一個1)。再比如7(0111)= 6(0110)+ 1(0001),所以7 & 6 = (0111)&(0110)= 6(0110),清除了7的二進制表示中最右邊的1(也就是最低位的1)。

代碼如下:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

/*int  NumberOf1(int n) {       //快速法
  int result = 0;
  while(n) {
  n = n & (n-1);
  result++;
  }
  return result;
  }*/
int NumberOf1(int n) {          //普通法
  int result = 0;
  int BitNum = sizeof(n)*8;
  for(int i=0;i<BitNum;++i) {
    if(n & 1)
      result++;
    n >>= 1;
  }
  return result;
}
int main() {
  cout<<NumberOf1(-8)<<endl;
  return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章