恰當的移位運算總是能夠讓代碼顯得很簡潔、很優雅,下面,就讓我們來看一下編程中使用頻率比較高的一些移位運算:
本程序在VS2010編譯器下運行,VS2010中,int佔4個字節(32位),下面程序也只針對int型變量(常量)進行考慮。
// shiftOperation.cpp : 定義控制檯應用程序的入口點。
/*******************************************
author:老六是Jerry
functoin:位運算
********************************************/
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//獲得int型最大值
cout<<((1<<31)-1)<<endl; //int佔4個字節,共可以表示2^32個數,由於可以表示負數,所以最大數爲2^31-1(最高位爲符號位)
//獲得int型最小值
cout<<(1<<31)<<endl; //int型表示的負數的最小值
cout<<"==============================\n";
//判斷奇偶性
int p=12344;
if((p&1)==1) //非常簡單的道理,奇數用二進制表示最後一位一定爲1,而偶數最後一位一定是0,所以與1(末位爲1,其它全0)做與操作即 可判斷
{
cout<<p<<"是奇數!"<<endl;
}
else
{
cout<<p<<"是偶數!"<<endl;
}
cout<<"==============================\n";
//不用臨時變量交換兩個數
//1.不用移位操作實現
int a=2,b=3;
a=a*b;
b=a/b;
a=a/b;
cout<<a<<","<<b<<endl;
int c=4,d=5;
c=c+d;
d=c-d;
c=c-d;
cout<<c<<","<<d<<endl;
//2.移位操作實現
int e=6,f=7;
//e=e^f; //第一步按位異或相當於把e和f不同的位找出來,存入e中,不同的位值爲1 (設e^f=g(g的值存在e中))
//f=f^e; //第二步將f與得到的不同的位的值按位異或,即會得到另一個值(e^f=g --> f^g=e)
//e=e^f; //第三步f已經轉換爲原來的e,所以用f和現在的e(存的是不同的位的信息)按位異或即可得到原f的值
//上面三步可以寫成一步
e^=f^=e^=f;
cout<<e<<","<<f<<endl;
cout<<"==============================\n";
//取絕對值
//原理:正數(考慮int類型)右移31位之後等於0,負數右移31位之後等於-1
int h=-6;
cout<<((h^(h>>31))-(h>>31))<<endl;
//若h是正數,h^0-0=h,值不變
//若h是負數,h^(-1)+1,將h的補碼與-1的補碼按位異或,再加1,得到絕對值
cout<<"==============================\n";
//取兩個數的較小、較大值
int i=2,j=3;
//取兩數的較大值
cout<<((j&((i-j)>>31)) | (i&(~(i-j)>>31)))<<endl; //若i-j>=0,右移31位後爲0,j&0=0;~(i-j)右移31位之後爲-1,i&-1=i (-1的補碼爲1111...1111)
//取兩數的較小值
cout<<((i&((i-j)>>31)) | (j&(~(i-j)>>31)))<<endl; //同理
cout<<"==============================\n";
//判斷一個數是不是2的冪
int k=31;
cout<<((k&(k-1))==0)<<endl; //若一個數是2的冪,則這個數轉換爲二進制後應該只有一位值爲1(符號位除外),-1之後此位置0,後面 的位全置1
cout<<"==============================\n";
//求兩個整數的平均值
int m=6,n=8;
//簡單方法,先相加再除以2
cout<<((m+n)>>1)<<endl;
//另一方法
cout<<((m^n)>>1)+(m&n)<<endl; //m^n得到兩數的對應位中有且僅有一個爲1的部分,併除以2,m&n得到對應位都爲1的部分,即得到平 均值
cout<<"==============================\n";
Sleep(5000);
return 0;
}