計算機編碼:java
符號位爲0表示正數,爲1表示負數;編碼
其他各位等同於真值的絕對值。spa
如:0000 0000 0000 0010 =2,1000 0000 0000 0010 =-2code
符號位的用法及正數的表示與「原碼」同樣;blog
負數的表示是在「原碼」表示的基礎上經過將符號位之外的各位取反來得到的。class
如:0000 0000 0000 0010 = 2,1111 1111 1111 1101 = -2基礎
符號位的用法及正數的表示與「原碼」同樣;擴展
負數的表示是在「反碼」的基礎上經過加1來得到的。硬件
如:0000 0010 = 2,1111 1110 = -2二進制
計算機中負數的表示均用補碼,負數參與的運算獲得的也是補碼
位運算符:
& 與。 全1爲1, 有0爲0。 任何數與0與都等於0。
| 或。 有1爲1, 全0爲0。 任何數與0或都等於原值。
~ 非。 逐位取反
^ 異或。 相同爲0,相異爲1。 任何數與0異或都等於原值。
Java基本類型的字節長度
java基本類型的的字節長度與具體的軟硬件環境無關。Java中的char類型用Unicode碼儲存。
各個類型長度爲:
byte : 1
short : 2
char : 2
int : 4
long : 8
float : 4
double: 8
boolean : 1
java各個類型的二進制編碼實例(System.out.println(Integer.toBinaryString(i));)
int i = 1;
二進制表示爲:(原碼)
00000000 00000000 00000000 00000001
int i = -1;
二進制表示爲:(補碼)
11111111 11111111 11111111 11111111
long l = 1;
二進制表示爲:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
特別注意:
負數都是用補碼錶示並參與運算的。獲得的也是補碼,須要減1取反得到原碼。
位運算事例
-1^1,
-1
1000 0000 0000 0000 0000 0000 0000 0001--原碼
1111 1111 1111 1111 1111 1111 1111 1110--反碼
1111 1111 1111 1111 1111 1111 1111 1111--補碼
1
0000 0000 0000 0000 0000 0000 0000 0001--原碼
則-1^1等於
1111 1111 1111 1111 1111 1111 1111 1111^
0000 0000 0000 0000 0000 0000 0000 0001=
1111 1111 1111 1111 1111 1111 1111 1110--補碼
1111 1111 1111 1111 1111 1111 1111 1101--反碼
1000 0000 0000 0000 0000 0000 0000 0010--原碼
即-1^1=-2
移位運算:
右邊補0,符號位就是被移動到的位.
正數:
x<<1通常至關於2x,可是可能溢出.
若x在這個範圍中: 2的30次方~(2的31次方-1) 二進制表示 0100...0000到0111...1111,<<後最高爲變爲1了,變成負數了.
負數:
x<<1通常也至關於2x,也有可能溢出.
若x在這個範圍中: -2的31次方~-(2的30次方+1)二進制表示1000...0000到1011...1111,<<後最高爲變成0了,變成正數了.
爲正數時左邊補0,爲負數時左邊補1.
x>>1,至關於x/2,餘數被捨棄,由於這個是縮小,因此不會溢出.
不過有一點要注意: -1右移多少位都是-1.(由於負數都是用補碼錶示,-1永遠是 11111...)
另外舍棄的餘數是正的:
3>>1=1 捨棄的餘數是1.
-3>>1=-2 捨棄的餘數也是1,而不是-1.
對於正數 x>>1和x/2相等
對於負數 x>>1和x/2不必定相等.
這個把符號位一塊兒移動,左邊補0
對於正數,>>>和>>是同樣的
對於負數,右移以後就變成正數
對char,byte或者short進行移位處理,那麼在移位進行以前,它們會自動轉換成一個int。
但在進行邏輯右移位時,也可能遇到一個問題。若對byte或short值進行右移位運算,
獲得的可能不是正確的結果(Java 1.0和Java 1.1特別突出)。它們會自動轉換成int類型,並進行右移位。
但「零擴展」不會發生,因此在那些狀況下會獲得-1的結果。
int i = -1; i >>>= 10; System.out.println(i); System.out.println(Integer.toBinaryString(i)); long l = -1; l >>>= 10; System.out.println(l); System.out.println(Long.toBinaryString(l)); short s = -1; s >>>= 10; System.out.println(s); System.out.println(Integer.toBinaryString(s)); byte b = -1; b >>>= 10; System.out.println(b); System.out.println(Integer.toBinaryString(b));
輸出結果
4194303 0000 0000 0011 1111 1111 1111 1111 1111 18014398509481983 0000 0000 0011 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 -1 1111 1111 1111 1111 1111 1111 1111 1111 -1 1111 1111 1111 1111 1111 1111 1111 1111
一道詭異的移位題
int i=-1;
int j=i>>>32;
System.out.println(j);
輸出結果爲 -1
JAVA進行移位運算中由於int是佔32位,進行移位的數是32的模,因此當i>>>32的時候就等於i>>>0,至關於沒有進行移位.