位运算符分析
在阅读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);
}
}
扩展阅读
慕课网:原码,反码,补码杂谈
参考链接
java Int 二进制原理与 +、-、>>、>>>、^、&计算_张井天的博客-CSDN博客
Java &、&&、|、||、^、<<、>>、~、>>>等运算符 - 云+社区 - 腾讯云