位移运算符
package com.lgf.operation;/** * 所有的整数类型(除了char 类型之外)都是有符号的整数。 * 这意味着他们既能表示正数,又能表示负数。Java 使用2的补码(two’s complement ) * 这种编码来表示负数,也就是通过将与其对应的正数的二进制代码取反(即将1变成0,将0变成1),然后对其结果加1。 * 例如,-42就是通过将42的二进制代码的各个位取反,即对00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。 * 要对一个负数解码,首先对其所有的位取反,然后加1。 * 例如-42,或11010110 取反后为00101001 ,或41,然后加1,这样就得到了42。 * @author lgf * */public class BitwiseOperators {public static void main(String[] args) {bitwiseNot();bitwiseAnd();bitwiseOr();bitwiseXOR();leftShiftOperator();rightShiftOperator();rightUnsignedShiftOperator();}/** * ~ 按位非(NOT)(一元运算) * 按位非也叫做补,一元运算符NOT“~”是对其运算数的每一位取反。 */public static void bitwiseNot(){int x = 42;// x = 00000000000000000000000000101010int y = ~x;// y = 11111111111111111111111111010101 = -43 x = -42;// x = 11111111111111111111111111010110 y = ~x;// y = 00000000000000000000000000101001 = 41}/** * & 按位与(AND) 二元 * 按位与运算符“&”,如果两个运算数都是1,则结果为1。其他情况下,结果均为零。 */public static void bitwiseAnd(){int x = 44;// x = 0101100 int y = 99;//y =1100011int z = x & y;//z = 0100000 = 1 * 2^5 = 32x = - 44;//x = 11111111111111111111111111010100y = 99;//y = 00000000000000000000000001100011z = x & y;//z = 00000000000000000000000001000000 = 1 * 2^6 = 64 }/** * | 按或(OR) 二元 * 按位或运算符“|”,任何一个运算数为1,则结果为1 */public static void bitwiseOr(){int x = 44;// x = 0101100 int y = 99;//y =1100011int z = x | y;//z = 1101111 = 111x = - 44;//x = 11111111111111111111111111010100y = 99;//y = 00000000000000000000000001100011z = x | y;//z = 11111111111111111111111111110111 = -9 }/** * ^ 按位异或(XOR) 二元 * 按位或运算符 " ^ ", * 如果两个运算数都是1,则结果为1。 * 其他情况下,结果均为零。 */public static void bitwiseXOR(){int x = 44;// x = 0101100 int y = 99;//y =1100011int z = x ^ y;//z = 1001111 = 79x = - 44;//x = 11111111111111111111111111010100y = 99;//y = 00000000000000000000000001100011z = x ^ y;//z = 11111111111111111111111110110111 = -73}/** * 左移运算符<<使指定值的所有位都左移规定的次数。 * 它的通用格式如下所示: value << num 这里 * num 指定要移位值value 移动的位数。也就是,左移运算符<<使指定值的所有位都左移num位。 * 每左移一个位,高阶位都被移出(并且丢弃),并用0填充右边。 * 这意味着当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃; * 当左移的运算数是long 类型时,每移动1位它的第63位就要被移出并且丢弃。 * * 在对byte 和short类型的值进行移位运算时,你必须小心。 * 因为你知道Java 在对表达式求值时,将自动把这些类型扩大为 int 型, * 而且,表达式的值也是int 型。对byte 和short类型的值进行移位运算的结果是int 型, * 而且如果左移不超过31位,原来对应各位的值也不会丢弃。 * 但是,如果你对一个负的byte 或者short类型的值进行移位运算,它被扩大为int 型后,它的符号也被扩展。 * 这样,整数值结果的高位就会被1填充。因此,为了得到正确的结果,你就要舍弃得到结果的高位。 * 这样做的最简单办法是将结果转换为byte 型。下面的程序说明了这一点: */public static void leftShiftOperator(){int x = 11;//x = 1011int y = x << 3;//y = 1011000x = -11;//x = 11111111111111111111111111110101y = x << 3;//y = 11111111111111111111111110101000byte i = 64;//i = 00100000064int j = i << 2;//j = 100000000256byte z = (byte)(i << 2);//z = 00000000 0int num = 0xFFFFFFE; // num = 00001111111111111111111111111110//i = 0 num=00011111111111111111111111111100 536870908for(i=0; i<5; i++) { //i = 1 num = 00111111111111111111111111111000 1073741816num = num << 1; //i = 2 num = 01111111111111111111111111110000 2147483632//printBinary(num);//i = 3 num = 11111111111111111111111111100000 -32}//i = 4 num = 11111111111111111111111111000000 -64num = -0xFFFFFFE; // num = 11110000000000000000000000000010 -268435454//i = 0 num = 11100000000000000000000000000100 -536870908for(i=0; i<5; i++) { //i = 1 num = 11000000000000000000000000001000 -1073741816num = num << 1; //i = 2 num = 10000000000000000000000000010000 -2147483632//printBinary(num);//i = 3 num = 00000000000000000000000000100000 32}//i = 4 num = 00000000000000000000000001000000 64}/** * 右移运算符>>使指定值的所有位都右移规定的次数。 * 它的通用格式如下所示: value >> num 这里, * num 指定要移位值value 移动的位数。 * 也就是,右移运算符>>使指定值的所有位都右移num位 * * 右移时,被移走的最高位(最左边的位)由原来最高位的数字补充。 * 例如,如果要移走的值为负数,每一次右移都在左边补1, * 如果要移走的值为正数,每一次右移都在左边补0, * 这叫做符号位扩展(保留符号位)(sign extension ),在进行右移操作时用来保持负数的符号 */public static void rightShiftOperator(){int x = 35;//x = 10001135int y = x >> 2;//y = 10008x = 32;//x = 100000y = x >> 2;//y = 10008x = -32;//x = 11111111111111111111111111100000-32y = x >> 2;//y = 11111111111111111111111111111000-8x = -1;//x = 11111111111111111111111111111111y = x >> 2;//y = 11111111111111111111111111111111}/** * 无符号右移运算符>>> * 不管运算数的初值是什么,你希望移位后总是在高位(最左边)补0。 * 这就是人们所说的无符号移动(unsigned shift )。 * 这时你可以使用Java 的无符号右移运算符>>> ,它总是在左边补0。 */public static void rightUnsignedShiftOperator(){int x = 35;//x = 10001135int y = x >>> 2;//y = 10008x = 32;//x = 100000y = x >>> 2;//y = 10008x = -32;//x = 11111111111111111111111111100000-32y = x >>> 2;//y = 001111111111111111111111111110001073741816x = -1;//x = 11111111111111111111111111111111y = x >>> 2;//y = 001111111111111111111111111111111073741823printBinary(y);}public static void printBinary(int i){System.out.println("数值 " + i + " 对应的二进制为: " + Integer.toBinaryString(i) + " 一共:" + Integer.toBinaryString(i).length() + " 位");}}