c/c++的位操作
《說明,本文章面向初學者,高手勿看,如有問題需要** 請發郵件: [email protected] 》
c/c++是一種系統程式語言,之所以這樣說其中乙個原因是是因為其提供的位操作的能力。其提供的位操作符直接對應於相關的彙編指令。在現實的程式設計實踐中,合理的使用位操作會大大提高效率。我先以乙個例子來開始我們的講解:
求乙個整數的絕對值
乍一看這個問題,我們一位這樣的問題太簡單了,所以你可能隨手會寫出這樣的程式:
inline int abs(int a)
^_^,或許此時你正在為你的傑作而沾沾自喜,呵呵這麼短小的函式,同時使用了inline,內聯之後減少函式呼叫的開銷,厲害啊,我怎麼就這麼有才呢?
先別急,我們來看一下這個程式有什麼問題:我們知道,現代的cpu都是嚴重依賴流水線的,不然的話他們的頻率怎麼會做的老高(ibm已經到4.6g了)。intel,amd的86的cpu的流水已經到十幾二十級了。所以這個時候,你一旦卡斷流水,那損失是相當大的。這個時候你會發現問題的所在了,原來你的程式卡斷了流水!!
這個時候你著急了,難道還有不用判斷的絕對值函式?有!首先我們來分析整數的表數方式:現代的計算機中,大多數是補碼表示的,負數呢就是原碼變反加1,正數就是原碼!如下:
-1: 00000000 00000000 00000000 00000001
---> 11111111 11111111 11111111 11111110 + 1
= 11111111 11111111 11111111 11111111
所以:設x、y為32位有符號整數,其中y=x>>31,則可以使用表示式(x^y)-y計算x的絕對值。由於x>>31是帶符號的向右位移,因此,x為負時,y為全1,即y等於-1;x非負時,y為全0,即y等於0。若非負,則x^y等於x,從而(x^y)-y等於x本身;若x為負,則x^y等於x按位取反,而減y等於加一,從而(x^y)-y等於x的絕對值。
inline int abs(int a)
(一).位運算子 & | ^ ~ << >>
這幾個運算子,相信已經很熟悉了,單數使用的時候未必真的用的很好。下面是乙個例子,你看看答案是多少?
int i= 1;
i = i<<1+2;
std::coutbit->bit31 = 1;
cout<
bitset<32>a;
bitset<32>b(2399);
bitset<32>c(string("1001"));
bitset<32>d(string("10011111"),4,3);
這三個例子說明了三種構造情況,呵呵看看中怎麼描述的:
bitset<32>a; a有32位,每位都為0
bitset<32>b(2399)=》bitsetb(u); b是unsigned long型u的乙個副本,當用unsigned long值作為bitset物件的初始值時,該值將轉化為二進位制的位模式。而bitset物件中的位集作為這種位模式的副本。如果bitset型別長度大於unsigned long值的二進位制位數,則其餘的高階位置為0;如果bitet型別長度小於unsigned long值的二進位制位數,則只使用unsigned值中的低階位,超過bitet型別長度的高階位將被丟棄
bitset<32>c(string("1001")); bitsetb(s); b是string物件s中含有的位串的副本
當用string物件初始化bitset物件時,string物件直接表示為位模式。從string物件讀入位集的順序是從右向左,string物件和bitset物件之間是反向轉化的:string物件的最右邊字元(即下標最大的那個字元)用來初始化bitset物件的低階位(即下標為0的位)。當用string物件初始化bitset物件時,記住這一差別很重要。
bitset<32>d(string("10011111"),4,3); bitsetb(s, pos, n) b是s中從位置pos開始的n個位的副本
(2 )操作:
b.any()
b中是否存在置為1的二進位制位?
b.none()
b中不存在置為1的二進位制位嗎?
b.count()
b中置為1的二進位制位的個數
b.size()
b中二進位制位的個數
b[pos]
訪問b中在pos處的二進位制位
b.test(pos)
b中在pos處的二進位制位是否為1?
b.set()
把b中所有二進位制位都置為1
b.set(pos)
把b中在pos處的二進位制位置為1
b.reset()
把b中所有二進位制位都置為0
b.reset(pos)
把b中在pos處的二進位制位置為0
b.flip()
把b中所有二進位制位逐位取反
b.flip(pos)
把b中在pos處的二進位制位取反
b.to_ulong()
用b中同樣的二進位制位返回乙個unsigned long值
os << b
把b中的位集輸出到os流
這麼多的操作,看花眼了,不用著急,給你個程式,ctrl c crtl v到你的編譯器中仔細看:
#include
#include
#include
using namespace std;
int main(int argc, char* argv)
(四)關於vector
所有關於位操作的書籍都會提及這個標準庫中的另類。呵呵如果你還不知道的話,建議你好好看看相關書籍,下面是幾個比較好的**:
如上所言,vector不是真正的stl容器,所以很多的操作跟vector並不相容,所以使用vector要小心。
(五)還有什麼容器適合於位操作呢?
boost::dynamic_bitset
大名頂頂的boost庫,不過這個還不是標準。
(寫完之後,覺得有點背離初衷,呵呵,還請各位原諒)
C C 位操作 位運算
在c語言中,可以單獨操控變數的位 bit 一般高階語言不會處理這級別的細節,c在提供高階語言便利的同時,還能為組合語言所保留的級別上工作,這使其成為編寫裝置驅動程式和嵌入式 的首選語言。目錄 二進位制整數 binary 有符號整數 八進位制 octal 十六進製制 hex 位運算子 按位與 的用途 ...
c c 中的位操作
c c 支援比較低階的位運算,在是眾人皆知的了。每本c c 的教科書都會說到這部分的內容,不過都很簡略,我想會有很多人不知道位運算用在什麼地方。這個帖子就簡略說說位運算的用處,更進一步的用法要大家自己去體會。而主要說的是操作標誌值方面。define bti msk bit 1 bit define ...
C C 中的位操作
1 位邏輯非運算 位邏輯非運算是單目的,只有乙個運算物件。位邏輯非運算按位對運算物件的值進行非運算,即 如果某一位等於0,就將其轉變為1 如果某一位等於1,就將其轉變為0。比如,對二進位制的10010001進行位邏輯非運算,結果等於01101110,用十進位制表示就是 145等於110 對二進位制的...