常用位運算規則
阿新 • • 發佈:2021-06-21
1、描述
- 計算機中所有的資料二進位制的形式儲存在裝置中。即 0、1 兩種狀態,計算機對二進位制資料進行的運算稱為位運算,而我們看到的十進位制數,則是計算機通過二進位制運算之後轉為了十進位制轉換的結果。
- 下面程式碼示例中會在變數後面註釋二進位制形式,以Java的int型別計算,int型別長度為4位元組,總共32位,第一位為符號位,1為負數,0為正數,如1的二進位制即為0000 0000 0000 0000 0000 0000 0000 0001,-1則為1000 0000 0000 0000 0000 0000 0000 0001,為了方便演示,會取一些各位數為變數的值,所以中間的0省略,正數寫成0...0001,負數寫成1...0001。
- 二級制運算中,是通過補碼運算,正數的補碼=反碼=原碼,負數的補碼=原碼取反 + 1,計算結果如果是符號位是0,則直接轉換十進位制,為1則先求補碼,再轉為十進位制。負數參與計算一樣。
2、"&" 與運算(兩個位都為1則為1)
public static void example1() { int i1 = 1; //0 ... 0001 int i2 = 0; //0 ... 0000 int i3 = 1; //0 ... 0001 /** 二進位制 十進位制 * 0 ... 0001 1 0 ... 0001 1 * & & * 0 ... 0000 0 0 ... 0001 1 * ___________________________________________________________ * 0 ... 0000 0 0 ... 0001 1 **/ System.out.println("i1 & i2 =" + (i1 & i2)); System.out.println("i1 & i3 =" + (i1 & i3)); }
//結果: i1 & i2 = 0 i1 & i3 = 1
3、"|" 或運算(一個為1則為1)
public static void example1() { int i1 = 1; //0 ... 0001 int i2 = 0; //0 ... 0000 int i3 = 1; //0 ... 0001 /** 二進位制 十進位制 * 0 ... 0001 1 0 ... 0001 1 * & & * 0 ... 0000 0 0 ... 0001 1 * ___________________________________________________________ * 0 ... 0000 0 0 ... 0001 1 **/ System.out.println("i1 & i2 = " + (i1 & i2)); System.out.println("i1 & i3 = " + (i1 & i3)); }
//結果: i1 | i2 = 1 i1 | i3 = 1
4、"^" 異或運算(兩個不同則為1)
public static void example3() { int i1 = 1; //0001 int i2 = 2; //0010 int i3 = 3; //0011 /** 二進位制 十進位制 * 0 ... 0001 1 0 ... 0001 1 * & & * 0 ... 0010 2 0 ... 0011 3 * ___________________________________________________________ * 0 ... 0011 3 0 ... 0010 2 **/ System.out.println("i1 ^ i2 =" + (i1 ^ i2)); System.out.println("i1 ^ i3 =" + (i1 ^ i3)); }
//結果: i1 ^ i2 = 3 i1 ^ i3 = 2
5、"<<" 左移運算(右邊補0,向左移動)
public static void example5() { int i1 = 1; //0001 int i3 = 3; //0011 /** 二進位制 十進位制 * 0 ... 0001 1 0 ... 0011 3 0 ... 0011 3 * << << << * _____________________________________________________________________________________ * 0 ... 0010 2 0 ... 0110 6 0 ... 1100 12 **/ System.out.println("i1 << 1 = " + (i1 << 1)); System.out.println("i3 << 3 = " + (i3 << 1)); System.out.println("i3 << 3 = " + (i3 << 2)); }
//結果: i1 << 1 = 2 i3 << 3 = 6 i3 << 3 = 12
6、">>" 右移運算(正數,左邊補0,向右移動;負數,左邊補1,向右移動)
public static void example8() { int i1 = 1; //0001 int i2 =-1; //1... 0001 int i3 = 3; //0011 /** 二進位制 十進位制 * 0 ... 0001 1 1 ... 0001 -1 0 ... 0011 3 * >> >> >> * _____________________________________________________________________________________ * 0 ... 0000 0 1 1... 0000 (反碼) -1 0 ... 0000 0 **/ System.out.println("i1 >> 1 = " + (i1 >> 1)); System.out.println("i2 >> 1 = " + (i2 >> 1)); System.out.println("i3 >> 3 = " + (i3 >> 2)); }
//結果: i1 >> 1 = 0 i2 >> 1 = -1 i3 >> 3 = 0
7、">>>"無符號右移(無視符號位,右移都補0)
public static void example6() { int i1 = 1; int i2 = -2; /** 二進位制 十進位制 * 0 ... 0001 1 1 ... 0010 -2 1 ... 0010 -2 * >>> >>> >>> * _____________________________________________________________________________________ * 0 ... 0000 0 0 1... 0000 0 11 ... 0000 **/ System.out.println("i1 >>> 1 =" + (i1 >>> 1)); System.out.println("i2 >>> 1 =" + (i2 >>> 1)); System.out.println("i2 >>> 2 =" + (i2 >>> 2)); }
//結果: i1 >>> 1 =0 i2 >>> 1 =2147483647 i2 >>> 2 =1073741823
8、"~" 取反運算
public static void example4() { int i1 = 1; //0001 1110 1...0001 + 0001 =0010 = -2 int i2 = 0; //0000 1111 1...0000 + 0001 =0001 = -1 /** 二進位制 十進位制 * 0 ... 0001 1 0 ... 0000 0 * ~ ~ * 1 ... 1110 1 ... 1111 * 1 ... 0001 1 ... 0000 * + + * 0 ... 0001 0 ... 0001 * ___________________________________________________________ * 1 ... 0010 -2 1 ... 0001 -1 **/ System.out.println("~i1 = " + (~i1)); System.out.println("~i2 = " + (~i2)); }
//結果: ~i1 = -2 ~i2 = -1