- 程序中的所有數(shù)在計(jì)算機(jī)內(nèi)存中都是以二進(jìn)制的形式儲(chǔ)存的。位運(yùn)算就是直接對(duì)整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作
Java 位運(yùn)算符:
& :按位與。
| :按位或。
^ :按位異或。
~ :按位取反。
<< :左位移運(yùn)算符。
>> :右位移運(yùn)算符。
>>> :無(wú)符號(hào)右移運(yùn)算符。
單位換算:
1個(gè)二進(jìn)制數(shù)據(jù)0或1 = 1bit(位)
1byte(字節(jié)) = 8bit
1k = 1024byte(字節(jié))
1M = 1024k
1G = 1024M
1T = 1024G
// 一個(gè)英文字符占1個(gè)字節(jié)
// 一個(gè)漢字占2個(gè)字節(jié)
// 一個(gè)int 類型的十進(jìn)制數(shù)占4個(gè)字節(jié)
一、計(jì)算
- 拿兩個(gè)十進(jìn)制的數(shù)來(lái)做例子:
13轉(zhuǎn)二進(jìn)制為:1101
14轉(zhuǎn)二進(jìn)制為:1110
tip:如果不熟悉二進(jìn)制可以看我之前的文章
-
&按位與
規(guī)則:參與運(yùn)算的兩個(gè)值,如果兩個(gè)相應(yīng)位都為1,則該位的結(jié)果為1,否則為0,例:
1101
& 1110
-------------
1100
即:13&14=1100(二進(jìn)制)= 12(十進(jìn)制)
-
|按位或
規(guī)則:參加運(yùn)算的兩個(gè)數(shù)只要兩個(gè)數(shù)中的一個(gè)為1,結(jié)果就為1
1101
| 1110
-------------
1111
即:13|14=1111(二進(jìn)制)= 15(十進(jìn)制)
-
^按位異或
規(guī)則:參加運(yùn)算的兩個(gè)數(shù),如果兩個(gè)相應(yīng)位為“異”(值不同),則該位結(jié)果為1,否則為0。例:
1101
^ 1110
-------------
0011
即:13^14=0011(二進(jìn)制)= 3(十進(jìn)制)
-
~按位取反
規(guī)則:取反的二進(jìn)制位全部取反,1變?yōu)?,0變?yōu)?.即
這里 引進(jìn)了3個(gè)概念:原碼,反碼、補(bǔ)碼。
原碼:在數(shù)值前面增加了一位符號(hào)位(即最高位為符號(hào)位):正數(shù)該位為0,負(fù)數(shù)該位為1,所以第一位表示符號(hào)位,其余位表示真值
反碼:正數(shù)的反碼與其原碼相同;負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號(hào)位不變,其余各個(gè)位取反.
補(bǔ)碼:正數(shù)的補(bǔ)碼與其原碼相同; 負(fù)數(shù)補(bǔ)碼為:符號(hào)位不變,其絕對(duì)值各位取反加1
// 我們知道正數(shù)的原碼 和補(bǔ)碼一樣,而且在計(jì)算機(jī)里面存的也是補(bǔ)碼
[13的補(bǔ)碼] 00001101
~13
---------------------
11110010 //取反操作:這個(gè)取反出來(lái)的是一個(gè)補(bǔ)碼,我們要求出原碼才能轉(zhuǎn)
//如果補(bǔ)碼的符號(hào)位為“1”,表示是一個(gè)負(fù)數(shù),求原碼的操作可以是:符號(hào)位為1,其余各位取反,然后再整個(gè)數(shù)加1??傻?
反碼,最高符號(hào)位不變= 10001101
在+1,可得 10001110
最高位為1說(shuō)明這是一個(gè)負(fù)數(shù)不做計(jì)算,真值為:1110=0+2+4+8=14
所以 ~13 = -14
- 如果補(bǔ)碼的符號(hào)位為“0”,表示是一個(gè)正數(shù),所以補(bǔ)碼就是該數(shù)的原碼。
- 如果補(bǔ)碼的符號(hào)位為“1”,表示是一個(gè)負(fù)數(shù),求原碼的操作可以是:符號(hào)位為1,其余各位取反,然后再整個(gè)數(shù)加1。
- 負(fù)數(shù)的補(bǔ)碼=反碼+1
-負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號(hào)位不變,其余各個(gè)位取反.
- 在Java中,因?yàn)橐苿?dòng)規(guī)則就是當(dāng)byte、short、char這三種類型做位移運(yùn)算的時(shí)候自動(dòng)轉(zhuǎn)換為int型,而int型是32位。所以結(jié)果就是按照回32位來(lái)的,大于等于32的數(shù)是取對(duì)32的余數(shù)計(jì)算。所以位移35位結(jié)果等于位移3位。
-
<<左位移運(yùn)算符。
a<<b 規(guī)則:將二進(jìn)制數(shù)a整個(gè)向左移b位,低位用0補(bǔ)齊,例:
// a=13 ,b=3
0000 0000 0000 0000 0000 0000 0000 1101
a<<b
-------------
0000 0000 0000 0000 0000 0000 0110 1000
0+0+0+8+0+32+64+0=104
即:a<<b=13<<3=01101000(二進(jìn)制)=104(十進(jìn)制)
個(gè)人結(jié)論:其實(shí)有個(gè)簡(jiǎn)單的算法,就是左移幾位就乘與2的幾次方。如上:132^3=138=104, 如果a為負(fù)數(shù),結(jié)果也為負(fù)數(shù)。
注意:如果b 大于32時(shí),則對(duì)b取模。當(dāng)b>32時(shí),b=b%32。比如當(dāng)b=36時(shí),其實(shí)只位移了36%32=4位。
-
>>右位移運(yùn)算符。
a>>b 規(guī)則: 指將二進(jìn)制數(shù)a整個(gè)向右移b位,低位舍棄,例:
// a=13 ,b=3
0000 0000 0000 0000 0000 0000 0000 1101
a>>b
-------------
0000 0000 0000 0000 0000 0000 0000 0001
即:a>>b=13>>3=00000001(二進(jìn)制)=1(十進(jìn)制)
// 是如果是負(fù)數(shù),位置不夠時(shí) 高位需要補(bǔ)1(正數(shù)高位補(bǔ)0)
// a=-13 ,b=3
原碼: 1000 0000 0000 0000 0000 0000 0000 1101
反碼: 1111 1111 1111 1111 1111 1111 1111 0010
補(bǔ)碼: 1111 1111 1111 1111 1111 1111 1111 0011
右移3位
補(bǔ)碼: 1111 1111 1111 1111 1111 1111 1111 1110 (負(fù)數(shù)補(bǔ)1)
原碼: 1000 0000 0000 0000 0000 0000 0000 0001+1=1000 0000 0000 0000 0000 0000 0000 0010=-2
-
>>>無(wú)符號(hào)右移運(yùn)算符。
a>>>b 規(guī)則: 指將二進(jìn)制數(shù)a整個(gè)向右移b位,不論正負(fù)數(shù),不夠補(bǔ)零
// a=13 ,b=3
0000 0000 0000 0000 0000 0000 0000 1101
a>>b
-------------
0000 0000 0000 0000 0000 0000 0000 0001
即:a>>>b=13>>>3=00000001(二進(jìn)制)=1(十進(jìn)制)
//如果是負(fù)數(shù)
//a =-13,b=3
-13
原碼: 1000 0000 0000 0000 0000 0000 0000 1101
反碼: 1111 1111 1111 1111 1111 1111 1111 0010
補(bǔ)碼: 1111 1111 1111 1111 1111 1111 1111 0011
右移3位
補(bǔ)碼: 0001 1111 1111 1111 1111 1111 1111 1110
原碼: 0001 1111 1111 1111 1111 1111 1111 1110
結(jié)果:0+2^1+2^2+2^3+.....+2^28=Sn
用等比數(shù)列求和公式計(jì)算就可以得出結(jié)果。
Sn=a1(1-q^n)/(1-q)=2*(1-2^28)/(1-2)=536870910