看了會《c程式語言》的位運算一節,重溫了下「位運算」的巧妙與高效。 與操作可以用來判斷乙個整數的奇偶性,依據二進位制的性質可以很容易得到這樣的結論,因此:
if a&1
a is odd;
else
a is even;
左移右移的應用應該更熟悉,可以方便進行*2和/2操作。之前遇到的應用有快速冪之類的。 學習程式設計的時候一般都會遇到這個問題:設計乙個程式,統計整數中值為1的二進位制位進行統計。一般的做法無非是:遍歷所有的位,測試每一位是否為1,為1則進行統計。
#includeusing namespace std;
int main()
// for
cout << cnt << endl;
}
有乙個更高效的做法就是,發現x&=(x-1),可以去除x中最右邊的值為1的乙個二進位制位(也就把最右邊為1的位變為0),譬如:x=1100,那麼x-1=1011,那麼x&(x-1)=1000。因為.....100000,假設最右邊第n為1,此數進行減1之後因為借位的原因變為了.....011111(第n位被借,1至n-1變為了1) ***100000 ***011111 & —————— ***000000 有這個提示,從而使統計跟高效:
#includeusing namespace std;
int main()
// while
cout << cnt << endl;
}
左移,右移和非運算的配合將很容易得到我們需要的遮蔽位,以32位整數為例,我們要將低位元組的3~8為設定為遮蔽位:
~0的結果為全1:
11111111 11111111 11111111 11111111
順勢左移6位:
11111111 11111111 11111111 11000000
非操作:
00000000 00000000 00000000 00111111
順勢左移2位:
00000000 00000000 00000000 11111100
同樣,右移也能夠達到這樣的效果,他們操作時互補的。
異或也可以很方便的把一二進位制整數中的某幾位取反,例如:
***001100***將此二進位制序列中的六位取反,一般不採取~取反運算子,因為它作用的單位是乙個short,int或者long。利用異或可以解決這個問題。
當兩位元進行異或運算時,如果兩位元相同,則結果為0;兩位元不同,則結果為1。發現當一位元與1進行異或時,其結果是此位元的非;當一位元與0進行異或時,結果不變。於是:
***001100***
000111111000 ^(遮蔽位的計算可以參照上面)
——————— ***110011***
乙個有趣的結論便是乙個整數連續異或同乙個數,其結果還是那個整數,這可以對某數進行簡單的加密。譬如:
101
110 ^(加密)
011
110 ^(解密)
101 拿去忽悠女生:
00000000 00000000 00000010 00001000(520)
00000000 00000000 00000101 00100010(1314)
本文完 2012-06-25
搗亂小子
有趣的位運算
今天看到知乎裡面看到兩個有趣的位運算,記錄一下 第乙個是判斷乙個數的奇 偶性 奇數返回 true boolean isodd int n 就我個人的理解說一下吧,按照二進位制轉換成十進位制的一種方式,最後的一位是 1 2的0次方或者是0 2的0次方。這個是int數末尾為1的時候就是奇數咯,為0的時候...
c語言有趣的位運算
應用 1.判斷奇偶 2.見後面有趣應用 本身異或為0,與0異或為本身,滿足交換律。應用 不借助第三個數交換兩數,有趣應用4 cpp view plain copy void swap int a,int b 可以這樣理解 第一步 a b 即a a b 第二步 b a 即b b a b 由於 運算滿足...
位運算 57 普通的位運算
要求說明 當 a 2,b 4,c 6,d 8時程式設計求a c b d a d a的值。解 單目運算子 都是對對應整數轉化成二進位制數後按位比較計算 兩個相應二進位中,都為1,該位為1,否則為0 兩個相應二進位中,有乙個1,該位為1,否則為0 兩個相應二進位,相同為0,不同為1 單目運算子,作用對二...