參與位運算的數字都是二進位制補碼的方式進行按位與、或、異或,所以先說說二進位制:原碼、反碼、補碼。
在c語言中,原碼、反碼、補碼都是有符號定點數的表示方法。乙個有符號定點數的最高位為符號位,0是正,1是負,下面統一以8位的整數為例介紹這幾種碼:
原碼:
如果機器字長為n,那麼乙個數的原碼就是用乙個n位的二進位制數,其中最高位為符號位:正數為0,負數為1。剩下的n-1位表示概數的絕對值。
例如: x=+101011 , [x]原= 00101011 x=-101011 , [x]原= 10101011
位數不夠的用0補全。
ps:正數的原、反、補碼都一樣:0的原碼跟反碼都有兩個,因為這裡0被分為+0和-0。
反碼:
正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
例如:x=-101011 , [x]原= 10101011 ,[x]反=11010100
補碼:
正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1
例如:x=-101011 , [x]原= 10101011 ,[x]反=11010100,[x]補=11010101
ps:0的補碼是唯一的,如果機器字長為8那麼[0]補=00000000。
乙個數和它的補碼是可逆的。
移碼:
不管正負數,將其補碼的符號位取反即可。
例如:x=-101011 , [x]原= 10101011 ,[x]反=11010100,[x]補=11010101,[x]移=01010101
所以我們可見,這幾種碼的關係是:原碼->反碼->補碼->移碼
下面簡單介紹下幾種位運算,都大同小異,注意他們的應用才是重點:
按位與運算 按位與運算子」&」是雙目運算子。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 運算 ( 255 的二進位制數為0000000011111111)。
用法:
a. 清零特定位 (mask中特定位置0,其它位為1,s=s&mask)
b. 取某數中指定位 (mask中特定位置1,其它位為0,s=s&mask)
按位或運算 按位或運算子「|」是雙目運算子。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有乙個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
應用:常用來將源運算元某些位置1,其它位不變。
按位異或運算 按位異或運算子「^」是雙目運算子。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現。
應用:
a. 使特定位的值取反 (mask中特定位置1,其它位為0 s=s^mask)
b. 不引入第三變數,交換兩個變數的值 (設 a=a1,b=b1)
關於異或的用法與在演算法上的應用,參考我的另一篇部落格:異或運算的應用與nimm博弈
補碼與位運算
3 按位或 4 按位異或 6 右移 位運算主要包括按位與 按位或 按位異或 取反 左移 右移 由於位運算直接操作的是記憶體,運算速度相對較快,採取位運算能有效提公升程式執行效率。如用右移代替除以2操作,1代替對2取餘操作 計算機中的資料按補碼形式儲存,因此在進行位運算時,直接操作的是補碼。正數的原碼...
補碼與位運算
計算機中的資料按補碼形式儲存,因此在進行位運算時,直接操作的是補碼。正數的原碼 反碼和補碼是其本身。對於負數而言,原碼轉補碼 符號位不變,其他位按位取反 反碼轉原碼 同原碼轉反碼,即反碼的反碼等於原碼 原碼轉補碼 符號位不變,其他位按位取反然後加1 補碼轉原碼 同原碼轉補碼,即補碼的補碼等於原碼。相...
位運算 補碼
令x x 1 x,直到x變為0。原理 x x 1 會把x的二進位制中最後乙個1變為0.整數x和2 n的模 x 2 n 1 原理 2 n 1 的二進位制是n個1,和x進行與運算,會保留x的二進位制的後n位 計算機中的有符號數有三種表示方法,即原碼 反碼和補碼。三種表示方法均有符號位和數值位兩部分,符號...