Java 中的 位运算符分析

位运算符分析

在阅读java源码的时候,常见一些移位运算符(&、|、^、<<、>>、~、>>>等),下面的分析可做参考。

/**
 * 
 * @author 尘浮者
 * @description Java &、|、^、<<、>>、~、>>>等位运算符分析
 * 参考链接
 * https://blog.csdn.net/zhangyong01245/article/details/83715717
 * https://cloud.tencent.com/developer/article/1338265
 * https://cloud.tencent.com/developer/article/1336599
 * 说明:数字是以补码的形式存在的,计算也是用补码来进行计算,计算后的结果也是补码
 * 但由于正数的原码、补码、反码一样,所以不用转,如果最终的计算的结果为负数,即最高位为1,那么你需要换算成原码才是正确答案。
 */
public class TestOperatorChar {
	
	public static void main(String[] args) {
		TestOperatorChar testOperatorChar = new TestOperatorChar();
		testOperatorChar.test1();//测试&符号
		testOperatorChar.test2();//测试|符号
		testOperatorChar.test3();//测试^符号
		testOperatorChar.test4();//测试~符号  (一元运算符:就是一个数就能完成操作)
		testOperatorChar.test5();//测试>>符号
		testOperatorChar.test6();//测试<<符号
		testOperatorChar.test7();//测试>>>符号
		
	}
	
	/**
	 * 测试&符号
	 * &按位与的运算规则是将两边的数转换为二进制位,然后运算最终值,运算规则即(两个为真才为真)1&1=1 , 1&0=0 , 0&1=0 , 0&0=0
	 * -11 原码 10000000 00000000 00000000 00001011
	 * -13 原码 10000000 00000000 00000000 00001101
	 * -11 补码 11111111 11111111 11111111 11110101
	 * -13 补码 11111111 11111111 11111111 11110011
	 * 根据计算规则得出
	 * -11&-13 的补码  11111111 11111111 11111111 11110001
	 * -11&-13 的补码补码既是原码 10000000 00000000 00000000 00001111 = -15
	 * 可以通过Integer的parseInt 和 parseUnsignedInt(不考虑符号位)去求得值,
	 * 注意,最多只能有31位,符号位,"-"代表负数, "+"或者"0"或者不填代表正数
	 */
	public void test1(){
		System.out.println("11&13 = " + (11&13));  		//9
		System.out.println("-11&-13 = " + (-11&-13));	//-15
		/*
		System.out.println(Integer.parseInt("-1111111111111111111111111111111",2));
		System.out.println(Integer.parseInt("+1111111111111111111111111111111",2));
		System.out.println(Integer.parseInt("01111111111111111111111111111111",2));
		System.out.println(Integer.parseInt("1111111111111111111111111111111",2));
		
		System.out.println(Integer.parseUnsignedInt("1111111111111111111111111111111",2));
		*/
	}
	
	/**
	 * 测试|符号
	 * |按位或和&按位与计算方式都是转换二进制再计算,不同的是运算规则(一个为真即为真)1|0 = 1 , 1|1 = 1 , 0|0 = 0 , 0|1 = 1
	 * -11 原码 10000000 00000000 00000000 00001011
	 * -13 原码 10000000 00000000 00000000 00001101
	 * -11 补码 11111111 11111111 11111111 11110101
	 * -13 补码 11111111 11111111 11111111 11110011
	 * 根据计算规则得出
	 * -11|-13 的补码  11111111 11111111 11111111 11110111
	 * -11|-13 的补码补码 10000000 00000000 00000000 00001001 = -9
	 * 
	 */
	public void test2(){
		System.out.println("11|13 = "+(11|13));  	//15
		System.out.println("-11|-13 = "+(-11|-13));	//-9
	}
	
	/**
	 * 测试^符号
	 * ^异或运算符顾名思义,异就是不同,其运算规则为1^0 = 1 , 1^1 = 0 , 0^1 = 1 , 0^0 = 0
	 * -11 原码 10000000 00000000 00000000 00001011
	 * -13 原码 10000000 00000000 00000000 00001101
	 * -11 补码 11111111 11111111 11111111 11110101
	 * -13 补码 11111111 11111111 11111111 11110011
	 * 根据计算规则得出
	 * -11^-13 的补码  00000000 00000000 00000000 00000110 = 6
	 */
	public void test3(){
		System.out.println("11^13 = "+(11^13));  //6
		System.out.println("-11^-13 = "+(-11^-13));//6
	}
	
	/**
	 * 测试~符号
	 * 取反就是1为0,0为1
	 * 11   原码 00000000 00000000 00000000 00001011
	 * -11 原码 10000000 00000000 00000000 00001011
	 * -11 补码 11111111 11111111 11111111 11110101
	 * 根据计算规则得出
	 * ~-11 的补码  00000000 00000000 00000000 00001010 = 10
	 * ~11的补码     11111111 11111111 11111111 11110100 
	 * ~11的补码的补码即原码 10000000 00000000 00000000 00001100 = -12
	 */
	public void test4(){
		System.out.println("~11 = "+~11);  //-12
		System.out.println("~-11 = "+~-11);//10
	}
	
	/**
	 * 测试>>符号  相当于除以2的n次方
	 * -20  	原码 10000000 00000000 00000000 00010100
	 * -20  	补码             11111111 11111111 11111111 11101100
	 * -20>>2即-20补码右移两位          11111111 11111111 11111111 111011
	 * 正数高位补0,负数补1
	 * 根据计算规则得出
	 * -20>>2 的补码  11111111 11111111 11111111 11111011
	 * -20>>2 的补码的补码即原码     10000000 00000000 00000000 00000101 = -5
	 * 
	 * -5  		原码 10000000 00000000 00000000 00000101
	 * -5	  	补码             11111111 11111111 11111111 11111011
	 * -5>>2即-5补码右移两位            11111111 11111111 11111111 111110
	 * 正数高位补0,负数补1
	 * 根据计算规则得出
	 * -5>>2 的补码  11111111 11111111 11111111 11111110
	 * -5>>2 的补码的补码即原码     10000000 00000000 00000000 00000010 = -2
	 * 
	 */
	public void test5(){
		System.out.println("-20>>2 = "+(20>>2));  //-5
		System.out.println("-5>>2 = "+(-5>>2));	  //-2
	}
	
	/**
	 * 测试<<符号 相当于乘以2的n次方
	 * 5  		原码    00000000 00000000 00000000 00000101
	 * 5<<2即5原码左移两位   000000 00000000 00000000 00000101
	 * 移除后,都在最后补上0(高位溢出,低位补0)
	 * 根据计算规则得出
	 * 5<<2 的原码  00000000 00000000 00000000 00010100 = 20
	 * 
	 * -3  		原码        10000000 00000000 00000000 00000011
	 * -3	  	补码        11111111 11111111 11111111 11111101
	 * -3<<2即-3补码左移两位	   111111 11111111 11111111 11111101
	 * 移除后,都在最后补上0(高位溢出,低位补0)
	 * 根据计算规则得出
	 * -3<<2 的补码  11111111 11111111 11111111 11110100
	 * -3<<2 的补码的补码即原码     10000000 00000000 00000000 00001100 = -12
	 */
	public void test6(){
		System.out.println("5<<2 = "+(5<<2));  	//20
		System.out.println("-3<<2 = "+(-3<<2));	//-12
	}
	
	/**
	 * 测试>>>符号 正数的无符号右移和>> 是一致的,
	 * 无符号右移运算符和右移运算符的主要区别在于负数的计算因为无符号右移是高位补0,所以等到的总是一个正数
	 * -1    原码 10000000 00000000 00000000 00000001
	 * -1    补码 11111111 11111111 11111111 11111111
	 * 移除后,都在高位补上0
	 * 根据计算规则得出
	 * -1>>>1 的补码    01111111 11111111 11111111 11111111 = Integer.MAX_VALUE
	 *	   
	 */
	public void test7(){
		System.out.println(-1 >>> 1);
	}
	
}

 

扩展阅读

慕课网:原码,反码,补码杂谈

知乎:在写代码的过程中使用位运算的好处?

 

参考链接

https://blog.csdn.net/zhangyong01245/article/details/83715717

https://cloud.tencent.com/developer/article/1338265

https://cloud.tencent.com/developer/article/1336599

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值