Java的位運算(bitwise operators)直接對整數類型的位進行操做,這些整數類型包括long、int、short、char和 byte,位運算符具體以下表:java
左移位(<<) ide
程序:spa
public class LeftMoving{blog
public static void main(String[] args){內存
System.out.println("5<<3="+(5<<3));字符串
}it
}io
輸出結果: 編譯
5<<3=40 class
計算過程:
0000 0000 0000 0000 0000 0000 0000 0101 ? 5
0000 0000 0000 0000 0000 0000 0010 1000 ? 40
右移位(>>)
正數
程序:
public class PlusRightMoving{
public static void main(String[] args){
System.out.println("5>>1="+(5>>1));
}
}
輸出結果:
5>>1=2
計算過程:
0000 0000 0000 0000 0000 0000 0000 0101 ? 5
0000 0000 0000 0000 0000 0000 0000 0010 ? 2
負數
程序:
public class NegativeRightMoving{
public static void main(String[] args){
System.out.println("-5>>1="+(-5>>1));
}
}
輸出結果:
-5>>1=-3
計算過程:
1111 1111 1111 1111 1111 1111 1111 1011 ? -5
1111 1111 1111 1111 1111 1111 1111 1101 ? -3
無符號右移位(>>>)
程序:
public class UnsignedRightMoving{
public static void main(String[] args){
System.out.println("-5>>>1="+(-5>>>1));
}
}
輸出結果:
-5>>>1=2147483645
計算過程:
1111 1111 1111 1111 1111 1111 1111 1011 ? -5
0111 1111 1111 1111 1111 1111 1111 1101 ? 2147483645
補充個Java中的基本數據類型的相關知識。
這裏包括了float和double兩個浮點型,在本文中對其不予考慮,由於位運算是針對整型的。進行位操做時,除long型外,其餘類型會自動轉成int型,轉換以後,可接受右操做數長度爲32。進行位運算時,老是先將短整型和字節型值轉換成整型值再進行移位操做的。
程序:
public class ByteLeftMoving{
public static void main(String[] args){
byte b = 127;
System.out.println("b<<3="+(b<<3));
System.out.println("(byte)(b<<3)="+(byte)(b<<3));
}
}
輸出結果:
b<<3=1016
(byte)(b<<3)=-8
程序:
public class CharLeftMoving{
public static void main(String[] args){
char c = 'l';
System.out.println("c<<3="+(c<<3));
System.out.println("(char)(c<<3)="+(char)(c<<3));
}
}
輸出結果:
c<<3=864
(char)(c<<3)=?
以上兩個例子所有編譯經過,由此能夠看出,當byte和char進行移位運算時不會發生錯誤,而且均按照整型進行計算,當計算結果超出byte或是char所能表示的範圍時則進行相應的轉換(分別輸出告終果-8和?)。
位運算中的操做數
在進行移位運算時要注意整型和長整型在內存中的位數(整型是32位,長整型是64位),若是移位操做數超出了該位數則取模計算,例如:int型數據是32位的,若是左移35位是什麼結果?
程序:
public class LeftMoving{
public static void main(String[] args){
System.out.println("5<<35="+(5<<35));
}
}
輸出結果:
5<<35=40
該結果與5<<3徹底相同。
不管正數、負數,它們的右移、左移、無符號右移 32位都是其自己,好比 -5<<32=-五、-5>>32=-五、-5>>>32=-5。
一個有趣的現象是,把 1 左移 31 位再右移 31位,其結果爲 -1。
計算過程以下:
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111
位運算要求操做數爲整數,操做數不能是字符串也不能是小數。
以下列程序:
public class BitMath{
public static void main(String[] args){
String s = "Hello";
long l = 99;
double d = 1.11;
int i = 1;
int j = 0;
System.out.println("j<<s="+j<<s); //編譯錯誤語句
System.out.println("j<<d="+j<<d); //編譯錯誤語句
System.out.println("i<<j="+i<<j); //編譯能夠經過
System.out.println("i<<l="+i<<l); //編譯能夠經過
}
}
因爲位運算是二進制運算,不要與一些八進制數搞混,java中二進制數沒有具體的表示方法。
public class BitMath{
public static void main(String[] args){
System.out.println("010|4="+(010|4));
}
}
輸出結果:
010|4=12
計算過程:
0000 0000 0000 0000 0000 0000 0000 1000 ?8
0000 0000 0000 0000 0000 0000 0000 0100 ?4
進行「或」計算結果爲:
0000 0000 0000 0000 0000 0000 0000 1100 ?12
當位運算中碰見負數,必須把它轉成補碼(不知道什麼是補碼的補習功課去)再進行計算,而不是使用原碼。
程序:
public class BitMath{
public static void main(String[] args){
try {
int x = -7;
System.out.println("x>>1="+(x>>1));
} catch(Exception e) {
System.out.println("Exception");
}
}
}
輸出結果:
x>>1=-4
計算過程:
1111 1111 1111 1111 1111 1111 1111 1001 ?-7
1111 1111 1111 1111 1111 1111 1111 1100 ?-4
public class BitMath{
public static void main(String[] args){
int i = 1;
int j = -1;
System.out.println("1>>>31="+(i>>>31));
System.out.println("-1>>31="+(j>>31));
}
}
輸出結果:
1>>>31=0
-1>>31=-1
程序:
public class BitMath{
public static void main(String[] args){
int a = 1;
a <<= 31;
a >>= 31;
a >>= 1;
System.out.println("a="+a);
int b = 1;
b <<= 31;
b >>= 31;
System.out.println("b="+b);
int c = 1;
c >>= 31;
c <<= 31;
System.out.println("c="+c);
}
}
輸出結果:
a=-1
b=-1
c=0
計算過程:
0000 0000 0000 0000 0000 0000 0000 0001 ?a=1
1000 0000 0000 0000 0000 0000 0000 0000 ?a=a<<31後,這裏被看成是負數
1111 1111 1111 1111 1111 1111 1111 1111 ?a=a>>31後,結果爲-1
1111 1111 1111 1111 1111 1111 1111 1111 ?a=a>>1後,結果仍爲-1
0000 0000 0000 0000 0000 0000 0000 0001 ?c=1
0000 0000 0000 0000 0000 0000 0000 0000 ?c=c>>31後爲0
0000 0000 0000 0000 0000 0000 0000 0000 ?0左移31位仍爲0