public class BitOperate {public static void bitCalc() {byte a = 12,b=10;byte c = -12,d=-10;/** * 1、按位與 & * (AND) * 運算方法:當兩邊運算元的位同時為1時,結果為1,否則為0 * * 注意:符號位也會參與運算 */// 12二進位表示(1100),10二機制(1010)System.out.println("正數與運算:"+(a&b)); //1100&1010=1000 == 8 //注意:負數電腦用補碼錶示:// -12:11110100, -10:11110110System.out.println("負數與運算:"+(c&d)); //(11110100)補=(10001100)原 == -12//System.out.println("正負數與運算:"+(a&d));//00001100&11110110 = 00000100 == 4 System.out.println();/** * 2、按位或 | * (OR) * 運算方法:當兩邊運算元的位有一邊為1時,結果為1,否則為0 * */System.out.println("正數或運算:"+(a|b)); //1100|1010=1110 == 14// -12:11110100, -10:11110110System.out.println("負數或運算:"+(c|d)); //(11110110)補=(10001010)原 == -10// 12:00001100, -10:11110110System.out.println("正負數或運算:"+(a|d)); //(11111110)補=(10000010)原 == -2System.out.println();/** * 3、按位非 ~ * (NOT) * 運算方法:運算元的位0變1,1變0 * */// 12: 00001100System.out.println("正數非運算:"+ (~a)); //11110011=(10001101)原 == -13// -12: 11110100System.out.println("負數非運算:"+ (~c)); //00001011 == 11System.out.println();/** * 4、按位異或 ^ * (XOR) * 運算方法: 對比每個數位上的0或1如果相同,那麼結果就取0,如果不同就取1 * */// 12: 00001100), 10: 00001010)System.out.println("正數異或運算:"+ (a^b)); //000000110 == 6// -12:11110100, -10:11110110System.out.println("負數異或運算:"+(c^d)); //00000010 == 2// 12:00001100, -10:11110110System.out.println("正負數異或運算:"+(a^d)); //(11111010)補=(10000110)原 == -6System.out.println("--------------------------------------------");/** * 移位元運算 * * 概念: * 移位元運算符就是在二進位的基礎上對數字進行平移。 * * 分類: * 按照平移的方向和填充數位規則分為三種:<<(左移)、>>(帶符號右移)和>>>(無符號右移)。 * * 運算方式: * 在移位元運算時,byte、short和char類型移位後的結果會變成int類型, * 對於byte、short、char和int進行移位時,規定實際移動的次數是移動次數和32的餘數, * 也就是移位33次和移位1次得到的結果相同。 * 移動long型的數值時,規定實際移動的次數是移動次數和64的餘數, * 也就是移動66次和移動2次得到的結果相同。 * * */ /** * 5、左移 << * * 運算方法: * 按二進位形式把所有的數字向左移動對應的位元,高位移出(捨棄),低位的空位補零。 * * 數學意義: * 在數字沒有溢出的前提下,對於正數和負數,左移一位都相當於乘以2的1次方,左移n位就相當於乘以2的n次方。 * *///before: 0000 0000 0000 0000 0000 0000 0000 1100//after: 0000 0000 0000 0000 0000 0000 0011 0000 == 48System.out.println("正數左移:"+(a<<2)); //a*2*2 = 48System.out.println("負數左移:"+(c<<2)); //c*2*2 = -48//數字溢出的情況://12//before: 0000 0000 0000 0000 0000 0000 0000 1100//<<28 after : 1100 0000 0000 0000 0000 0000 0000 0000//<<29 after : 1000 0000 0000 0000 0000 0000 0000 0000 -0補碼代表最小負數2的31次方就是-2147483648System.out.println("正數左移溢出:"+(a<<28)); //-1073741824System.out.println("正數左移溢出:"+(a<<29)); //-2147483648//-12//before: 1111 1111 1111 1111 1111 1111 1111 0100//<<28after : 0100 0000 0000 0000 0000 0000 0000 0000//<<28after : 1000 0000 0000 0000 0000 0000 0000 0000System.out.println("負數左移溢出:"+(c<<28)); //1073741824System.out.println("負數左移溢出:"+(c<<29)); //-2147483648System.out.println();/** * 5、有符號右移 >> * * 運算方法: * 按二進位形式把所有的數字向右移動對應的位元,低位移出(捨棄),高位的空位補符號位,即正數補零,負數補1。 * * 數學意義: * 在數字沒有溢出的前提下,右移一位相當於除2,右移n位相當於除以2的n次方。 * *///10 : 0000 0000 0000 0000 0000 0000 0000 1010//>>2after: 0000 0000 0000 0000 0000 0000 0000 0010 System.out.println("正數有符號右移:"+(b>>2)); //a/2*2 = 2//-10:1111 1111 1111 1111 1111 1111 1111 0110//>>2after: 111111 1111 1111 1111 1111 1111 1111 1101System.out.println("負數有符號右移:"+(d>>2)); //-3System.out.println();/** * 5、無符號右移 >>> * * 運算方法: * 按二進位形式把所有的數字向右移動對應的位元,低位移出(捨棄),高位的空位補零。 * 對於正數來說和帶符號右移相同,對於負數來說不同。 * * 其他結構和>>相似。 * *///10 : 0000 0000 0000 0000 0000 0000 0000 1010//>>>2after: 0000 0000 0000 0000 0000 0000 0000 0010 System.out.println("正數無符號右移:"+(b>>>2)); // 正數的情況與>>相同//-10:1111 1111 1111 1111 1111 1111 1111 0110//>>>2after: 001111 1111 1111 1111 1111 1111 1111 1101System.out.println("負數無符號右移:"+(d>>>2)); //負數高位補0:1073741821}public static void main(String[] args) {BitOperate.bitCalc();}}
運算結果:
正數與運算:8負數與運算:-12正負數與運算:4正數或運算:14負數或運算:-10正負數或運算:-2正數非運算:-13負數非運算:11正數異或運算:6負數異或運算:2正負數異或運算:-6--------------------------------------------正數左移:48負數左移:-48正數左移溢出:-1073741824正數左移溢出:-2147483648負數左移溢出:1073741824負數左移溢出:-2147483648正數有符號右移:2負數有符號右移:-3正數無符號右移:2負數無符號右移:1073741821
/** * byte、short類型左移 * * 會自動轉換為int類型進行右移 */public static void bitShift() {byte a = 64, b; int i; i = a << 2; b = (byte) (a << 2); System.out.println("Original value of a: " + a); System.out.println("i (int): " + i + "----- b(byte): " + b); }
結果:
Original value of a: 64i (int): 256----- b(byte): 0
移位元運算的總結:
1.對於左移運算:
1>每左移一個位,高階位都被移出(並且丟棄),並用0填充右邊。這意味著當左移的運算數是int 類型時,每移動1位,它的第31位就要被移出並且丟棄;當左移的運算數是long 類型時,每移動1位它的第63位就要被移出並且丟棄。
2>左移都可以使原來的運算元翻倍,程式員們經常使用這個辦法來進行快速的2 的乘法。但是你要小心,如果你將1移進高階位(31或63位),那麼該值將變為負值。
3>在對byte 和short類型的值進行移位元運算時 , Java將自動把這些類型擴大為 int 型,而且,移位後的值也是int 型;如果左移不超過31位,原來對應各位的值不會丟棄。但是,如果你對一個負的byte 或者short類型的值進行移位元運算,它被擴大為int 型後,它的符號也被擴充,結果的高位就會被1填充。因此,為了得到正確的結果,你就要捨棄得到結果的高位。這樣做的最簡單辦法是將移位元運算的結果再轉換成byte 型 。
2.對於右移運算:每右移一次,就相當於將該值除以2並且捨棄了餘數。你可以利用這個特點將一個整數進行快速的2的除法。當然,你一定要確保你不會將該數原有的任何一位移出。
3.無符號右移(>>>)與右移的區別:每一次右移,>>運算子總是自動地用它的先前最高位的內容補它的最高位。這樣做保留了原值的符號。而無符號移動總是在高位(最左邊)補0。
4.與C、C++不同,Java中沒有無符號型整數,而且明確規定了整型和浮點型資料所佔的記憶體位元組數,這樣就保證了安全性、魯棒性和平台無關性。