【這裡我們將討論一些位操作技巧,如果使用得當會有助於提高你編出的程式執行速度】
我們程式設計或多或少會使用到位操作,位操作是程式設計中處理整型資料高效方法。例如,想要求出乙個整數二進位制位中值為 1 的個數,簡單的方法是用乙個迴圈,其實我們用一兩個位操作的小技巧就能高效的解決。
假設讀者已經知道整型資料二進位制補碼表示方式和位操作的基本方式。
我列出下文中將要使用的位操作標記:
& -bitwise and| -bitwise or
^ -bitwise xor
~ -bitwise not
<< -bitwise shift left
>> - bitwise shift right
本文中使用的數字是8bit無符號整型,二進位制補碼表示,用『x』標記,結果用『y』表示。數『x』的每一位元位標記為b7, b6, b5, b4, b3, b3, b2, b1 和 b0。b7 是符號位,權重最大,b0 權重最小。
我們從最簡單的開始逐漸過渡到難的。
技巧1:檢查整數是奇數還是偶數
if ((x & 1) == 0)else
相信很多人都知道這個方法,只要整數的最後一位位元是 1 ,那它就是奇數,反之就是偶數。即 b0 位要麼是 1 要麼是 0 ,『x』和 1 與(&)運算,保留了最 b0 位,如果 b0 是 1 ,『x』是奇數,如果 b0 位是 0 ,『x』是偶數。
如果還不是很清楚我們去乙個整數,例如43,二進位制表示為00101011,注意 b0 位為 1,我們將 43 與 1 做 & 運算:
100101011
2& 00000001 (note: 1
is the same as
00000001
)3 --------
400000001
從中看到 & 運算怎樣擦除了高位的 b7 ~ b1 位的資料只保留了 b0 位,結果為 1,因此知道 43 是奇數。
技巧2:測試第n位位元
if (x & (1
前面討論過了第一位位元測試,這裡做了一些改進,可以測試第任意位位元,只要將與運算的1向左平移相應的位數即可。假設向左平移n位,接下來的與運算就是只保留第n位,其它位都清零了。
下面是簡單的演示:
100000001 (same as
1<<0)1
<<1
00000010
1<<2
00000100
1<<3
00001000
1<<4
00010000
1<<5
00100000
1<<6
01000000
1<<7
10000000
小例子:
122的第三位位元是1嗎?(從0開始數)可以這樣做:
122 & (1<<3)
122的二進位制表示是01111010,(1<<3)即1向左平移3位元00001000。
101111010
2& 00001000
3 --------
400001000
我們看到結果不為0,這題的答案是1。
技巧3:將第n位設為1
y = x | (1《和前面的技巧一樣,只是把與運算(&)換成了或運算(|)。與1進行或運算將參與運算的位置為1,與0進行或運算參與預算的位不變。
看乙個例子:
假設我們要將120的第2位比特設為1:
101111000 (120
inbinary)
2| 00000100 (1
<<2
)3 --------
401111100
技巧4:將第n位設為0
y = x & ~(1《這個方法的關鍵就是~(1<~1
11111110 (same as ~(1
<<0
))~(1
<<1) 11111101
~(1<<2) 11111011
~(1<<3) 11110111
~(1<<4) 11101111
~(1<<5) 11011111
~(1<<6) 10111111
~(1<<7) 01111111
與『x』與運算的結果是清零了第n位,不管這一位是1還是0,其它位保持不變。
小例子,將127的第4位設為0:
101111111 (127
inbinary)
2& 11101111 (~(1
<<4
))3 --------
401101111
技巧5:將第n位取反
y = x ^ (1《這次使用的是異或運算,如果異或運算的兩個運算元相同,運算結果是0,兩個運算元不同,結果是1。怎樣將第n位取反呢?如果第n位位元為1,將它與1進行異或運算結果就是0,如果它是0,那麼它與1異或運算的結果就是1。於是這一位就取反了。
小例子,假設要將值01110101的第5位取反:
101110101
2^ 00100000
3 --------
401010101
同樣的數,第5位是0結果如下:
101010101
2^ 00100000
3 --------
401110101
注意到沒?對乙個數進行兩次同樣的異或運算後結果還是原來的數,這個漂亮的特性可以用在許多程式設計問題中。
6位你必須知道的產品大神
因為他們,我們才信仰產品經理是ceo學前班。1 賈伯斯 說到產品經理,必須說到賈伯斯。這個改變了世界的 神 在20多年裡至少上了7次美國 時代周刊 封面。我最近在三刷他的官方自傳 史蒂夫 賈伯斯傳 其實他還是很慘,說自己的親生父母不過是精子庫和卵子庫。儘管父母是高階知識分子,還是讓賈伯斯成了被遺棄的...
Linux世界你必須知道的
突然從windows世界轉向linux世界,也許剛開始或多或少都有點不太適應,慢慢地,也許你會發現linux的博大精深,最重要的是linux世界的很多東西都是free license,下面列舉一下linux世界你需要或必須知道的二三事。unix like 叫做 類unix 系統,主要指各種各樣的li...
你必須知道的關於tcp keepalive 設定
1.引數設定 檢視相關的引數 sysctl a grep tcp keepalive net.ipv4.tcp keepalive intvl 30 net.ipv4.tcp keepalive probes 2 net.ipv4.tcp keepalive time 160 設定相關的引數 sys...