被程序员忽视的位运算
在博客園潛水好久了,今天興致高昂的想寫一篇博客,寫的內(nèi)容就是最近剛剛弄懂的關(guān)于位運(yùn)算的題目。可能對(duì)那些老鳥(niǎo)老說(shuō)這些是在基礎(chǔ)不過(guò)的東西了,但是我相信還是有很多的博客需要了解并掌握這個(gè)基礎(chǔ)的。
?
做題目前首先需要掌握的知識(shí):
~?????????? 取反運(yùn)算符,如果運(yùn)算位為1取反后則變?yōu)?,如果運(yùn)算為為0取反后則為1
&?????????? 與運(yùn)算符,當(dāng)運(yùn)算的兩個(gè)數(shù)同時(shí)為1時(shí),則與運(yùn)算的結(jié)果才為1,否則為0
|???????????? 或運(yùn)算符,當(dāng)運(yùn)算的兩個(gè)數(shù)只要有一個(gè)1時(shí),則或運(yùn)算的結(jié)果為1,否則為0.
^ 異或運(yùn)算符,當(dāng)兩個(gè)運(yùn)算位不同時(shí)為1,相同時(shí)是0
>>????????? 右移運(yùn)算符
<<????????? 左移運(yùn)算符
?
在內(nèi)存中的運(yùn)算都是以補(bǔ)碼的形式存在的。
正數(shù)的原碼、反碼、補(bǔ)碼相同。
負(fù)數(shù)的原碼:最高為符號(hào)為0代表正、1代表負(fù)。后面的數(shù)為整數(shù)轉(zhuǎn)換后的二進(jìn)制數(shù)。
負(fù)數(shù)的反碼:除符號(hào)為以外的位進(jìn)行取反,1變?yōu)?,0變?yōu)?
負(fù)數(shù)的補(bǔ)碼:負(fù)數(shù)的反碼+1
?
這里舉個(gè)簡(jiǎn)單的負(fù)數(shù)的例子,這里以整數(shù)占4個(gè)字節(jié)為例:
整數(shù)-5
(-5)10 的原碼為:(10000000 00000000 00000000 00000101)2
(-5)10 的反碼為:(11111111 11111111 11111111 11111010)2
(-5)10 的補(bǔ)碼為:(11111111 11111111 11111111 11111011)2
?
算術(shù)右移:低位溢出,符號(hào)位不變,并用符號(hào)位補(bǔ)溢出的高位。
算術(shù)左右:符號(hào)位不變,低位補(bǔ)0
?
基礎(chǔ)知識(shí)就這么點(diǎn)了。不過(guò)這里沒(méi)有必要死記,在一邊做題目的時(shí)候,一邊在看定義,這樣對(duì)于理解會(huì)很有幫助的。
題目1
~2????????
因?yàn)?2為正數(shù),所以2的原碼等于2的反碼等于2的補(bǔ)碼
因?yàn)橛?jì)算中的運(yùn)算都是以補(bǔ)碼的形式存在的。所以我們需要2的補(bǔ)碼為(00000000 00000000 00000000 00000010)2
對(duì)2的補(bǔ)碼進(jìn)行取反運(yùn)算得到: (11111111 11111111 11111111 11111101)2
此時(shí)得到的結(jié)論為(~2)的補(bǔ)碼為 (11111111 11111111 11111111 11111101)2
因?yàn)樽罡呶粸?,所以是負(fù)數(shù)看,負(fù)數(shù)的補(bǔ)碼等于負(fù)數(shù)的反碼+1
所以又可以得到了(~2)的反碼為 (11111111 11111111 11111111 11111100)2
根據(jù)反碼又可以得到(~2)的原碼為 (10000000 00000000 00000000 00000011)2
最后我們把二進(jìn)制數(shù)轉(zhuǎn)化為十進(jìn)制數(shù)-3.
所以~2=-3
?????????????
?
題目2
2&3 2|3
因?yàn)?、3都為正數(shù),所以2、3的原碼等于反碼等于補(bǔ)碼。
? ? ? 即(2)10的原碼、反碼、補(bǔ)碼為 ? (00000000 00000000 00000000 00000010)2
? ? ? ? (3)10的原碼、反碼、補(bǔ)碼為 ? (00000000 00000000 00000000 00000011)2
??????緊接著我們開(kāi)始與運(yùn)算
???????????????????? 00000000 00000000 00000000 00000010
????????????? ?& ? 00000000 00000000 00000000 00000011
? ? 00000000 00000000 00000000 00000010
?
在接著我們開(kāi)始或運(yùn)算
???????????????????? 00000000 00000000 00000000 00000010
????????????? ?| ? ? ? 00000000 00000000 00000000 00000011
? ?00000000 00000000 00000000 00000011
這與、或運(yùn)算的結(jié)果為補(bǔ)碼,我們還需要進(jìn)行轉(zhuǎn)化成原碼。
? ? ? 因?yàn)樽罡邽?(符號(hào)位),所以表示整數(shù)。
即原碼等于反碼等于補(bǔ)碼。
所以2&3的原碼用二進(jìn)制表示為 ?00000000 00000000 00000000 00000010
? ? ? 轉(zhuǎn)化成十進(jìn)制為2
2|3的原碼用二進(jìn)制表示為 00000000 00000000 00000000 00000011
? ? ? 轉(zhuǎn)化成十進(jìn)制為3
?
題目3
13&7
同樣我們可以從題目中知道13、7都是正數(shù),所以正數(shù)的原碼等于反碼等于補(bǔ)碼。
? ? ? 即(13)10的原碼等于反碼等于補(bǔ)碼為 (00000000 00000000 00000000 00001101)2
(7)10的原碼等于反碼等于補(bǔ)碼為 ?(00000000 00000000 00000000 00000111)2?
最后我們?cè)谀X子里模擬在內(nèi)存中的運(yùn)算:
00000000 00000000 00000000 00001101
????????????? & ? ? ?00000000 00000000 00000000 00000111
? ? ?00000000 00000000 00000000 00000101
從結(jié)果中我們可以看出補(bǔ)碼的最高位符號(hào)位為0表示正數(shù)。
所以(13&7)10的原碼等于 (00000000 00000000 00000000 000000101)2
轉(zhuǎn)化成十進(jìn)制數(shù)為5
?
題目4
5|4?????????
同樣我們可以從題目中知道5、4都是正數(shù),所以正數(shù)的原碼等于反碼等于補(bǔ)碼。
? ? ? 即(5)10的原碼等于反碼等于補(bǔ)碼為 (00000000 00000000 00000000 00000101)2
(4)10的原碼等于反碼等于補(bǔ)碼為 (00000000 00000000 00000000 00000100)2?
最后我們?cè)谀X子里模擬在內(nèi)存中的運(yùn)算:
00000000 00000000 00000000 00000101
????????????? | ? 00000000 00000000 00000000 00000100
? 00000000 00000000 00000000 00000101
從結(jié)果中我們可以看出補(bǔ)碼的最高位符號(hào)位為0表示正數(shù)。
所以(5|4)10的原碼等于 (00000000 00000000 00000000 000000101)2
轉(zhuǎn)化成十進(jìn)制數(shù)為5
?
整數(shù)相對(duì)而言還是相對(duì)簡(jiǎn)單得,接著我們?cè)趤?lái)看幾個(gè)負(fù)數(shù)的題目。
題目5
(~-5)
首先我們可以知道-5是負(fù)數(shù)
? ? ? 所以我們要先轉(zhuǎn)化成原碼
? ? ? (-5)10的原碼為 (10000000 00000000 00000000 00000101)2
? ? ? ?在轉(zhuǎn)化成為反碼
(-5)10的反碼為 (11111111 11111111 11111111 11111010)2
在轉(zhuǎn)化成為補(bǔ)碼
(-5)10的補(bǔ)碼為 (11111111 11111111 11111111 11111011)2
? ? ? ?得到了補(bǔ)碼我們可以開(kāi)始取反運(yùn)算了:
? ? ? (~-5)10的補(bǔ)碼為 ? (00000000 00000000 00000000 00000100)2
? ? ? ?這里可以看到最高為符號(hào)位為0,所以表示的是整數(shù)。
? ? ? ?正數(shù)的原碼等于反碼等于補(bǔ)碼。
? ? ? ?所以(~-5)10的原碼為 ? (00000000 00000000 00000000 00000100)2
? ? ? ?最后(~-5)=4
緊接著我們來(lái)看左移運(yùn)算符和右移運(yùn)算符。
?題目6
-1>>2
因?yàn)槭?1是負(fù)數(shù),所有我們先通過(guò)一系列的轉(zhuǎn)化得到他的補(bǔ)碼。
? ? ?(-1)10 的原碼為: (10000000 00000000 00000000 00000001)2
(-1)10 的反碼為: ? ? (11111111 11111111 11111111 11111110)2
(-1)10 的補(bǔ)碼為: ?(11111111 11111111 11111111 11111111)2
? ? ? ? ?緊接著我們開(kāi)始右移運(yùn)算,溢出位用符號(hào)位來(lái)補(bǔ)。右移2位得到
(-1>>2)10 的補(bǔ)碼為: (11111111 11111111 11111111 11111111)2
? ? ? ?因?yàn)榉?hào)位為1,所以是負(fù)數(shù),我們接著算出反碼,原碼。
(-1>>2)10 的反碼為: (11111111 11111111 11111111 11111110)2
(-1>>2)10 的原碼為: (10000000 00000000 00000000 00000001)2
所有-1>>2=-1
?
-1<<2
? ? ? 我直接用上面的到的
(-1)10 的補(bǔ)碼為: (11111111 11111111 11111111 11111111)2
? ? ? ?緊接著我們?cè)趯?duì)他進(jìn)行左移,低位用0補(bǔ)。左移兩位得到的結(jié)果是
(-1<<2)10 的補(bǔ)碼為: (11111111 11111111 11111111 11111100)2
因?yàn)榉?hào)位為1,所以是負(fù)數(shù),我們接著算出反碼,原碼。
(-1<<2)10 的反碼為: (11111111 11111111 11111111 11111011)2
(-1>>2)10 的原碼為: (10000000 00000000 00000000 00000100)2
所有-1<<2=-4
?
題目7
1>>2
因?yàn)?是正數(shù),所有原碼等于反碼等于補(bǔ)碼,即
(1)10 的原碼等于反碼等于補(bǔ)碼為 (00000000 00000000 00000000 00000001)2
緊接著我們開(kāi)始右移運(yùn)算,
(1>>2)10 的補(bǔ)碼為 (00000000 00000000 00000000 00000000)2
因?yàn)榉?hào)位為0,所有原碼等于反碼等于
補(bǔ)碼為 (00000000 00000000 00000000 00000000)2
所有1>>2=0
?
1<<2
因?yàn)?是正數(shù),所有原碼等于反碼等于補(bǔ)碼,即
(1)10 的原碼等于反碼等于補(bǔ)碼為 (00000000 00000000 00000000 00000001)2
緊接著我們開(kāi)始右移運(yùn)算,
(1>>2)10 的補(bǔ)碼為 ?(00000000 00000000 00000000 00000100)2
因?yàn)榉?hào)位為0,所有原碼等于反碼等于
補(bǔ)碼為 (00000000 00000000 00000000 00000100)2
所有1<<2=4
?
題目8
-3^3
?????? 首先-3的為負(fù)數(shù),所以
(-3)10 的原碼為 (10000000 00000000 00000000 00000011)2
(-3)10 的反碼為 (11111111 11111111 11111111 11111100)2
(-3)10 的原碼為 (11111111 11111111 11111111 11111101)2
在因?yàn)?為正數(shù)則
(3)10 的原碼等于反碼等于補(bǔ)碼為 (00000000 00000000 00000000 00000011)2
緊接著我們開(kāi)始異或運(yùn)算
11111111 11111111 11111111 11111101
????????????? ^???? 00000000 00000000 00000000 00000011
? 11111111 11111111 11111111 11111110
(-3^3) 10 的補(bǔ)碼為 (11111111 11111111 11111111 11111110)2
因?yàn)榉?hào)位為1,所有是負(fù)數(shù),所有
(-3^3) 10 的反碼為 (11111111 11111111 11111111 11111101)2
(-3^3) 10 的原碼為 (10000000 00000000 00000000 00000010)2
所有(-3^3)=-2
?
?
題目暫時(shí)就先這么多,因?yàn)槲覀円獙W(xué)會(huì)舉一反三的思想。當(dāng)然上面只不過(guò)是我們的理論知識(shí),但是我們程序員需要有一種用代碼檢驗(yàn)真理的思想,我這里檢驗(yàn)的代碼用的是php,因?yàn)樗恼投际怯蟹?hào)的。
下面附上php代碼
/*運(yùn)行環(huán)境Win7 64位旗艦版*服務(wù)器IIS7.5*代碼語(yǔ)言PHP*編寫日期2012-5-31*編寫人:JimmyWu* */<html><head><title>位運(yùn)算練習(xí)</title><meta http-equiv="content-type" content="text/html;charset=utf-8" /></head> <body><?phpecho '整形的長(zhǎng)度'.PHP_INT_SIZE.'<br />';//位運(yùn)算echo '~2='.(~2).'<br />';echo '2&3='.(2&3).'<br />';echo '2|3='.(2|3).'<br />';echo '~-5='.(~-5).'<br />';echo '13&7='.(13&7).'<br />';echo '5|4='.(5|4).'<br />';echo '-3^3='.(-3^3).'<br />';echo '-1>>2 = '.(-1>>2).'<br />';echo '1>>2 = '.(1>>2).'<br />';echo '-1<<2 = '.(-1<<2).'<br />';echo '1<<2 = '.(1<<2).'<br />';?> </body> </html>
如果不對(duì)請(qǐng)指出并給我留言。最后歡迎關(guān)注我,也歡迎技術(shù)上的交流。
?
轉(zhuǎn)載于:https://www.cnblogs.com/Jimmy009/archive/2012/05/31/2528992.html
總結(jié)
以上是生活随笔為你收集整理的被程序员忽视的位运算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java 批注
- 下一篇: fastreport 中 给数值形数据做