public class BitOperation {
public static void main(String[] args) {
/*
* 计算机内部在做数学运算时(也就是计算机的0和1的运算),都是以补码为标准的
* 正数的原、反、补码都是它本身;
* 负数的原码最高为为1开头,反码是最高符号位不变,其余位在原码的基础上取反,
* 补码是在反码的基础上+1即可得到
*/
int a = 10;
int b = 2;
int c = opposites(a);
int d = leftShift(a, b);
int e = andOperation(a, b);
int f = orOperation(a, b);
int g = xorOperation(a, b);
int h = rightShift(a, b);
System.out.println(c + "," + d + "," + e + "," + f + "," + g + "," + h);
}
private static int rightShift(int a, int b) {
int h = a >> b;
/*
* 参加运算的两个数,换算为二进制(0、1)后,进行右移运算,用来将一个数各二进制位全部向右移动若干位。
*
* 假设a=10,b=2
* a的补码 = 0000 0000 0000 0000 0000 0000 0000 1010
* a >> b (向右两位:舍弃右边两位,左边边补两个0)= 0000 0000 0000 0000 0000 0000 0000 0010 (补码的结果)
* 转为原码 = 0000 0000 0000 0000 0000 0000 0000 0010
* 转为十进制 = 2;
*/
return h;
}
private static int xorOperation(int a, int b) {
int g = a ^ b;
/*
* 参加运算的两个数,换算为二进制(0、1)后,进行异或运算。只有当相应位上的数字不相同时,该为才取1,若相同,即为0。
* 假设a = 10 ,b = 2;
* a的补码 = 0000 0000 0000 0000 0000 0000 0000 1010;
* b的补码 = 0000 0000 0000 0000 0000 0000 0000 0010;
* 按位异或运算
* a ^ b = 0000 0000 0000 0000 0000 0000 0000 1000;
* 转为反码 = 0000 0000 0000 0000 0000 0000 0000 1000;
* 转为原码 = 0000 0000 0000 0000 0000 0000 0000 1000;
* 转为十进制 = 8;
*
*/
return g;
}
private static int orOperation(int a, int b) {
int f = a | b;
/*
* 参加运算的两个数,换算为二进制(0、1)后,进行或运算。只要相应位上存在1,那么该位就取1,均不为1,即为0。
* 假设a = 10 ,b = 2;
* a的补码 = 0000 0000 0000 0000 0000 0000 0000 1010;
* b的补码 = 0000 0000 0000 0000 0000 0000 0000 0010;
* 按位或运算
* a | b = 0000 0000 0000 0000 0000 0000 0000 0010;
* 转为反码 = 0000 0000 0000 0000 0000 0000 0000 1010;
* 转为原码 = 0000 0000 0000 0000 0000 0000 0000 1010;
* 转为十进制 = 10;
*
*/
return f;
}
private static int andOperation(int a, int b) {
int e = a & b;
/*
* 参加运算的两个数,换算为二进制(0、1)后,进行与运算。只有当相应位上的数都是1时,该位才取1,否则该为为0。
* 假设a = 10 ,b = 2;
* a的补码 = 0000 0000 0000 0000 0000 0000 0000 1010;
* b的补码 = 0000 0000 0000 0000 0000 0000 0000 0010;
* 按位与运算
* a & b = 0000 0000 0000 0000 0000 0000 0000 0010;
* 转为反码 = 0000 0000 0000 0000 0000 0000 0000 0010;
* 转为原码 = 0000 0000 0000 0000 0000 0000 0000 0010;
* 转为十进制 = 2;
*
*/
return e;
}
private static int leftShift(int a, int b) {
int d = a << b;
/*
* 参加运算的两个数,换算为二进制(0、1)后,进行左移运算,用来将一个数各二进制位全部向左移动若干位。
*
* 假设a=10,b=2
* a的补码 = 0000 0000 0000 0000 0000 0000 0000 1010
* a << b (向左移两位:舍弃左边两位,右边补两个0)= 0000 0000 0000 0000 0000 0000 0010 1000 (补码的结果)
* 转为原码 = 0000 0000 0000 0000 0000 0000 0010 1000
* 转为十进制 = 40;
*/
return d;
}
private static int opposites(int a) {
int c = ~a;
/*
* 参加运算的两个数,换算为二进制(0、1)后,进行取反运算。每个位上都取相反值,1变成0,0变成1。
*
* 正数 a = 10; a的原码 = 0000 0000 0000 0000 0000 0000 0000 1010 (int 32位);
* a的补码 = 0000 0000 0000 0000 0000 0000 0000 1010
* 按位取反:将操作数所对应的二进制表达式的每一个位进行取反计算,取反后所得到的值就是~按位取反的运算结果
* ~a的结果 = 1111 1111 1111 1111 1111 1111 1111 0101;这是补码的结果,需要转换为原码
* 先将补码转换为反码:反码= 补码-1 = 1111 1111 1111 1111 1111 1111 1111 0101 - 1 = 1111 1111 1111 1111 1111 1111 1111 0100
* 再转为反码 = 1000 0000 0000 0000 0000 0000 0000 1011
* 得到 ~a * = -11;
*
* 负数 a = -10;
* a的原码= 1000 0000 0000 0000 0000 0000 0000 1010;
* a的补码= 1111 1111 1111 1111 1111 1111 1111 0110;
* 按位取反: 将操作数所对应的二进制表达式的每一个位进行取反计算,取反后所得到的值就是~按位取反的运算结果
* ~a = 0000 0000 0000 0000 0000 0000 0000 1001
* 看得出来这是个正数,所以原码、反码、补码都是一样的
* 所以~a = 9
* 符合按位取反的规律: ~n = -(n + 1);
*/
return c;
}
}
控制台输出结果:-11,40,2,10,8,2