一,(&)与,(|)或,(~)非,(^)异或运算
位运算都是针对当前数的二进制数来进行的运算,所以在运算时要用当前数转化为的二进制格式来做分析。由于计算机底层都是用二进制保存数字,所以用位运算可以加快运算速度。下面的二进制为了简便,舍去了前面的0做比较。
(&)与运算
对于二进制,相同位都为1,结果才为1,否则结果为0。
表达式 二进制数1 二进制数2 结果
![](https://i-blog.csdnimg.cn/blog_migrate/ac6471692b07afd74a24dd0697a589b7.png)
(2)(|)或运算
对于二进制,相同位只要有一个为1,那么结果就是1,否则就为0。
csdn的表格中放(|)会出问题,就用中文来表示了
(3)(~)非运算
对于二进制,相同位为0,结果是1,如果位为1,结果是0。
需要明白一点的是,在计算机中 正数,负数都是通过补码的形式保存的,而正数的补码是其本身的原码,而负数的补码则要根据其绝对值的原码转化为反码,然后通过加1的操作得到补码的。在计算机内部存储中如int和long类型二进制首位为1就代表负数,为0就是正数。(记得这样保存负数的方法是由冯诺依曼提出的。《计算机与人脑》有讲解负数)
可以记一个结果:
正数取反 为取负后减一
负数取反 为取正后减一
^)异或运算
对于二进制,相同位相同则结果为0,不同则结果为1。
//& 与运算 对于二进制,相同位都为1,结果才为1,否则结果为0
System.out.println(2&3); // 10 11 10
System.out.println(5&3); // 101 011 001 //只要一个为0就为0
//|(或运算) 对于二进制,相同位只要有一个为1,那么结果就是1,否则就为0
System.out.println(5|7); // 101 111 010
System.out.println(3|4); // 011 100 111
//~(非运算)
//对于二进制,相同位为0,结果是1,如果位为1,结果是0
//正数取反 为对应负数减一
//负数取反 为对应正数减一
System.out.println(~7); //10001000 -8
System.out.println(Integer.toBinaryString(7)); //查看二进制
System.out.println(Integer.toBinaryString(-8));
System.out.println(~-4);
System.out.println(Integer.toBinaryString(-4)); //查看二进制
System.out.println(Integer.toBinaryString(3));
//^ 异或运算符^ (用英文输入法)
// 对于二进制,相同位相同则结果为0,不同则结果为1
System.out.println(2^3); // 10 11 --01 第1位相同,第2位不同 保留第2位
System.out.println(1^3); // 01 11 --10 第2位相同,第1位不同 保留第2位
System.out.println(3^4); // 011 100 --111
二,位移运算
(为简便部分省去了前面的0或1)
-
(<<) 向左位移
无论正负数,后面补零。左移多少就补多少个0。结果为乘以2的n次方。
-
(>> ) 向右位移
向右位移,正数前面补零,负数前面补1。结果为除以2的n次方。
(>>>)无符号右移
无符号位移,无论正负数,前面补零。正数不影响运算,负数会从最大正数开始递减。
System.out.println("<< 向左位移 ,无论正负数,后面补零。结果为乘以2的n次方");
System.out.println("3左移1位:"+(3<<1)); //00011--->00110
System.out.println("3左移2位:"+(3<<2)); //00011--->001100
System.out.println("3左移3位:"+(3<<3)); //00011--->011000
System.out.println("3左移6位:"+(3<<6)); //00011--->11000000
System.out.println("-3左移1位:"+(-3<<1));
// System.out.println(Integer.toBinaryString(-3));
// System.out.println(Integer.toBinaryString(-6));
System.out.println(" >> 向右位移,正数前面补零,负数前面补1。结果为除以2的n次方");
System.out.println("12右移1位:"+(12>>1)); //001100--->000110
System.out.println("12右移2位:"+(12>>2)); //001100--->000011
System.out.println("12右移3位:"+(12>>3)); //001110--->000001
System.out.println("-12右移2位:"+(-12>>2));
System.out.println(Integer.toBinaryString(-12));
System.out.println(">>>无符号位移,无论正负数,前面补零。正数不影响运算,负数会从最大正数开始递减。");
System.out.println("12无符号位移1位:"+(12>>>1)); //001100--->000110
System.out.println("12无符号位移3位:"+(12>>>3)); //001110--->000001
System.out.println("-12无符号位移2位:"+(-12>>>2));
System.out.println(Integer.toBinaryString(-12));
System.out.println(Integer.toBinaryString(1073741821));