/** * ~ 按位非(NOT)(一元运算) * 按位非也叫做补,一元运算符NOT“~”是对其运算数的每一位取反。 */ public static void bitwiseNot(){ int x = 42; // x = 00000000000000000000000000101010 int 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 = 1100011 int z = x & y; // z = 0100000 = 1 * 2^5 = 32
x = - 44; // x = 11111111111111111111111111010100 y = 99; // y = 00000000000000000000000001100011 z = x & y; // z = 00000000000000000000000001000000 = 1 * 2^6 = 64 }
/** * | 按或(OR) 二元 * 按位或运算符“|”,任何一个运算数为1,则结果为1 */ public static void bitwiseOr(){ int x = 44; // x = 0101100 int y = 99; // y = 1100011 int z = x | y; // z = 1101111 = 111
x = - 44; // x = 11111111111111111111111111010100 y = 99; // y = 00000000000000000000000001100011 z = x | y; // z = 11111111111111111111111111110111 = -9 }
/** * ^ 按位异或(XOR) 二元 * 按位或运算符 " ^ ", * 如果两个运算数都是1,则结果为1。 * 其他情况下,结果均为零。 */ public static void bitwiseXOR(){ int x = 44; // x = 0101100 int y = 99; // y = 1100011 int z = x ^ y; // z = 1001111 = 79
x = - 44; // x = 11111111111111111111111111010100 y = 99; // y = 00000000000000000000000001100011 z = 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 = 1011 int y = x << 3; // y = 1011000
x = -11; //x = 11111111111111111111111111110101 y = x << 3; //y = 11111111111111111111111110101000 byte i = 64; // i = 001000000 64 int j = i << 2; // j = 100000000 256 byte z = (byte)(i << 2); // z = 00000000 0
int num = 0xFFFFFFE; // num = 00001111111111111111111111111110 //i = 0 num=00011111111111111111111111111100 536870908 for(i=0; i<5; i++) { //i = 1 num = 00111111111111111111111111111000 1073741816 num = num << 1; //i = 2 num = 01111111111111111111111111110000 2147483632 //printBinary(num); //i = 3 num = 11111111111111111111111111100000 -32 } // i = 4 num = 11111111111111111111111111000000 -64
num = -0xFFFFFFE; // num = 11110000000000000000000000000010 -268435454 // i = 0 num = 11100000000000000000000000000100 -536870908 for(i=0; i<5; i++) { // i = 1 num = 11000000000000000000000000001000 -1073741816 num = 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 = 100011 35 int y = x >> 2; // y = 1000 8
x = 32; // x = 100000 y = x >> 2; // y = 1000 8
x = -32; // x = 11111111111111111111111111100000 -32 y = x >> 2; // y = 11111111111111111111111111111000 -8
x = -1; // x = 11111111111111111111111111111111 y = x >> 2; // y = 11111111111111111111111111111111 }
/** * 无符号右移运算符>>> * 不管运算数的初值是什么,你希望移位后总是在高位(最左边)补0。 * 这就是人们所说的无符号移动(unsigned shift )。 * 这时你可以使用Java 的无符号右移运算符>>> ,它总是在左边补0。 */ public static void rightUnsignedShiftOperator(){ int x = 35; // x = 100011 35 int y = x >>> 2; // y = 1000 8
x = 32; // x = 100000 y = x >>> 2; // y = 1000 8
x = -32; // x = 11111111111111111111111111100000 -32 y = x >>> 2; // y = 00111111111111111111111111111000 1073741816
x = -1; // x = 11111111111111111111111111111111 y = x >>> 2; // y = 00111111111111111111111111111111 1073741823 printBinary(y); }