位运算,原码、反码、补码、按位取反、按位与、按位或、按位异或、按位左移、按位右移(有错误请请指出)

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值