Java中的位运算符有如下几类
- 左移 <<
- 又移 >>
- 无符号右移 >>>
- 位与 &
- 位或 |
- 位非 ~
- 位异或 ^
左移 <<
public static void main(String[] args)
{
System.out.println(Integer.toBinaryString(10));
System.out.println(10 << 2);
System.out.println(Integer.toBinaryString(10 << 2));
}
在java中对一个数字左移n位,其实就是给该数字乘以2的n次方,比如10<<2,就是给10乘以2的平方,得到40。
那么二进制的方式是怎么实现的呢?上述代码输出结果如下:
1010
40
101000
//补全 int 32位十进制,如下
0000 0000 0000 0000 0000 0000 0000 1010
40
0000 0000 0000 0000 0000 0000 0010 1000
可以看出是将1010左移两位,低位补零所得。
因为Java中,int数字有符号,并且有长度限制,所能表示的范围为-2^31 ~ 2^31 -1(-2147483648~2147483647),因此如果左移所得结果超过2^37 - 1,将会变成负数;负数左移超过 -2^37 之后将会变成0,-2^37无论左移多少(除过32以及32的倍数位)位,结果始终为0。
public static void main(String[] args)
{
System.out.println(Integer.toBinaryString(2147483647));
System.out.println(2147483647 << 1);
System.out.println(Integer.toBinaryString(2147483647 << 1));
System.out.println("-------------------------------------");
System.out.println(Integer.toBinaryString(-2147483648));
System.out.println(-2147483648 << 1);
System.out.println(-2147483648 << 100);
System.out.println(Integer.toBinaryString(-2147483648 << 100));
}
结果如下:
1111111111111111111111111111111
-2
11111111111111111111111111111110
-------------------------------------
10000000000000000000000000000000
0
0
0
注意1左移31位所得既是int所能表示的做小整数,但是1左移32位不会得到0,而是1,不同于直接将-2147483648左移1位
public static void main(String[] args)
{
System.out.println(1 << 31);
System.out.println(Integer.toBinaryString(1 << 31));
System.out.println(-2147483648 << 1);
System.out.println(1 << 32);
}
-2147483648
10000000000000000000000000000000
0
1
任一数字左移32(或者32倍数)位将得到其本身
public static void main(String[] args)
{
System.out.println(1 << 32);
System.out.println(2147483647 << 32);
System.out.println(-1 << 32);
System.out.println(-2147483648 << 64);
}
1
2147483647
-1
-2147483648
右移 >>
在java中对一个数字右移n位,其实就是给该数字除以2的n次方,向下取整。正整数右移取到0之后,右移任何(除了32以及32的倍数)位,都是0;负整数右移得到-1之后,右移任何(除了32以及32的倍数)位,都是-1。
任一数字右移32(或者32的倍数)位将得到其本身
比如10>>2,就是10除以2的平方,取整得到2,-10>>2,就是-10除以2的平方向下取整,得到-3。
public static void main(String[] args)
{
System.out.println("1 >> 1 : " + (1 >> 1));
System.out.println("1 >> 20 : " + (1 >> 20));
System.out.println("1 >> 32 : " + (1 >> 32));
System.out.println("10 >> 2 : " + (10 >> 2));
System.out.println("10 >> 4 : " + (10 >> 4));
System.out.println("10 >> 30 : " + (10 >> 30));
System.out.println("10 >> 64 : " + (10 >> 64));
System.out.println("---------------------------------------");
System.out.println("-1 >> 2 : " + (-1 >> 2));
System.out.println("-1 >> 20 : " + (-1 >> 20));
System.out.println("-1 >> 32 : " + (-1 >> 32));
System.out.println("-10 >> 2 : " + (-10 >> 2));
System.out.println("-10 >> 3 : " + (-10 >> 3));
System.out.println("-10 >> 4 : " + (-10 >> 4));
System.out.println("-10 >> 30 : " + (-10 >> 30));
System.out.println("-10 >> 96 : " + (-10 >> 96));
}
1 >> 1 : 0
1 >> 20 : 0
1 >> 32 : 1
10 >> 2 : 2
10 >> 4 : 0
10 >> 30 : 0
10 >> 64 : 10
---------------------------------------
-1 >> 2 : -1
-1 >> 20 : -1
-1 >> 32 : -1
-10 >> 2 : -3
-10 >> 3 : -2
-10 >> 4 : -1
-10 >> 30 : -1
-10 >> 96 : -10
无符号右移 >>>
通常所说的右移即有符号右移,对于正整数来说,有符号右移与无符号右移是一样的,对于负整数来说,有符号右移高位补1,无符号右移高位补0。
任一数字无符号右移32(或者32的倍数)位,得到其本身
public static void main(String[] args)
{
System.out.println("10 : " + Integer.toBinaryString(10));
System.out.println("10 >> 1 : " + Integer.toBinaryString(10 >> 1) + " : " + (10 >> 1));
System.out.println("10 >>> 1 : " + Integer.toBinaryString(10 >>> 1) + " : " + (10 >>> 1) );
System.out.println("10 >> 2 : " + Integer.toBinaryString(10 >> 2) + " : " + (10 >> 2) );
System.out.println("10 >>> 2 : " + Integer.toBinaryString(10 >>> 2) + " : " + (10 >>> 2) );
System.out.println("10 >>> 32 : " + Integer.toBinaryString(10 >>> 32) + " : " + (10 >>> 32) );
System.out.println("--------------------------------------------------");
System.out.println("-10 : " + Integer.toBinaryString(-10));
System.out.println("-10 >> 1 : " + Integer.toBinaryString(-10 >> 1) + " : " + (-10 >> 1));
System.out.println("-10 >>> 1 : " + Integer.toBinaryString(-10 >>> 1) + " : " + (-10 >>> 1) );
System.out.println("-10 >> 2 : " + Integer.toBinaryString(-10 >> 2) + " : " + (-10 >> 2) );
System.out.println("-10 >>> 2 : " + Integer.toBinaryString(-10 >>> 2) + " : " + (-10 >>> 2) );
System.out.println("-10 >>> 32 :" + Integer.toBinaryString(-10 >>> 32) + " : " + (-10 >>> 32) );
}
10 : 1010
10 >> 1 : 101 : 5
10 >>> 1 : 101 : 5
10 >> 2 : 10 : 2
10 >>> 2 : 10 : 2
10 >>> 32 : 1010 : 10
--------------------------------------------------
-10 : 11111111111111111111111111110110
-10 >> 1 : 11111111111111111111111111111011 : -5
-10 >>> 1 : 1111111111111111111111111111011 : 2147483643
-10 >> 2 : 11111111111111111111111111111101 : -3
-10 >>> 2 : 111111111111111111111111111101 : 1073741821
-10 >>> 32 :11111111111111111111111111110110 : -10
如上实验,-10>>1位,与-10>>>1所得二进制码相差一位,其实是高位补0,补全32位如下:
-10 : 11111111111111111111111111110110
-10 >> 1 : 11111111111111111111111111111011 : -5
-10 >>> 1 : 01111111111111111111111111111011 : 2147483643
-10 >> 2 : 11111111111111111111111111111101 : -3
-10 >>> 2 : 00111111111111111111111111111101 : 1073741821
-10 >>> 32 :11111111111111111111111111110110 : -10
位与 &
位与,是将数字在二进制形式下,并且都补齐到32位,然后逐一对两个数的每一位进行比较,相同则得1,否则得0,最终得到的二进制为结果。
- 所有数字与0位与运算都得到0;
- 所有数字与-1位与运算都得到数字本身;
- 所有正数与231-1位与运算都得到本身,与-231位与都得到0;
- 所有负数与231-1位与运算都得到231+负数,与-231位与都得到-231;
public static void main(String[] args)
{
System.out.println("2147483647 : " + Integer.toBinaryString(2147483647));
System.out.println("-2147483648 : " + Integer.toBinaryString(-2147483648));
System.out.println("-1 : " + Integer.toBinaryString(-1));
System.out.println("0 : " + Integer.toBinaryString(0));
System.out.println("---------------------------------------------------------");
System.out.println("10 : " + Integer.toBinaryString(10));
System.out.println("1 : " + Integer.toBinaryString(1));
System.out.println("10&1 : " + Integer.toBinaryString(10&1) + "|" + (10&1));
System.out.println("10&-8: " + Integer.toBinaryString(10&-8) + "|" + (10&-8));
System.out.println("---------------------------------------------------------");
System.out.println("-10 : " + Integer.toBinaryString(-10));
System.out.println("-2 : " + Integer.toBinaryString(-2));
System.out.println("1 : " + Integer.toBinaryString(1));
System.out.println("-10&-2: " + Integer.toBinaryString(-10&-2) + "|" + (-10&-2));
System.out.println("-10&1 : " + Integer.toBinaryString(-10&1) + "|" + (-10&1));
System.out.println("---------------------------------------------------------");
System.out.println("10&-1: " + Integer.toBinaryString(10&-1) + "|" + (10&-1));
System.out.println("100&-1: " + Integer.toBinaryString(100&-1) + "|" + (100&-1));
System.out.println("2147483647&-1: " + Integer.toBinaryString(2147483647&-1) + "|" + (2147483647&-1));
System.out.println("-2147483648&-1: " + Integer.toBinaryString(-2147483648&-1) + "|" + (-2147483648&-1));
System.out.println("---------------------------------------------------------");
System.out.println("10&0: " + Integer.toBinaryString(10&0) + "|" + (10&0));
System.out.println("-10&0: " + Integer.toBinaryString(-10&0) + "|" + (-10&0));
System.out.println("2147483647&0: " + Integer.toBinaryString(2147483647&0) + "|" + (2147483647&0));
System.out.println("-2147483648&0: " + Integer.toBinaryString(-2147483648&0) + "|" + (-2147483648&0));
System.out.println("---------------------------------------------------------");
System.out.println("2147483647&-2147483648: " + Integer.toBinaryString(2147483647&-2147483648) + "|" + (2147483647&-2147483648));
System.out.println("-10&2147483647 : " + Integer.toBinaryString(-10&2147483647) + "|" + (-10&2147483647));
System.out.println("-123&2147483647 : " + Integer.toBinaryString(-123&2147483647) + "|" + (-123&2147483647));
System.out.println("10&2147483647 : " + Integer.toBinaryString(10&2147483647) + "|" + (10&2147483647));
System.out.println("-10&-2147483648 : " + Integer.toBinaryString(-10&-2147483648) + "|" + (-10&-2147483648));
System.out.println("-123&-2147483648 : " + Integer.toBinaryString(-123&-2147483648) + "|" + (-123&-2147483648));
System.out.println("10&-2147483648 : " + Integer.toBinaryString(10&-2147483648) + "|" + (10&-2147483648));
}
2147483647 : 1111111111111111111111111111111
-2147483648 : 10000000000000000000000000000000
-1 : 11111111111111111111111111111111
0 : 0
---------------------------------------------------------
10 : 1010
1 : 1
10&1 : 0|0
10&-8: 1000|8
---------------------------------------------------------
-10 : 11111111111111111111111111110110
-2 : 11111111111111111111111111111110
1 : 1
-10&-2: 11111111111111111111111111110110|-10
-10&1 : 0|0
---------------------------------------------------------
10&-1: 1010|10
100&-1: 1100100|100
2147483647&-1: 1111111111111111111111111111111|2147483647
-2147483648&-1: 10000000000000000000000000000000|-2147483648
---------------------------------------------------------
10&0: 0|0
-10&0: 0|0
2147483647&0: 0|0
-2147483648&0: 0|0
---------------------------------------------------------
2147483647&-2147483648: 0|0
-10&2147483647 : 1111111111111111111111111110110|2147483638
-123&2147483647 : 1111111111111111111111110000101|2147483525
10&2147483647 : 1010|10
-10&-2147483648 : 10000000000000000000000000000000|-2147483648
-123&-2147483648 : 10000000000000000000000000000000|-2147483648
10&-2147483648 : 0|0
位或 |
位或,是将数字在二进制形式下,并且都补齐到32位,然后逐一对两个数的每一位进行比较,任一数字该位为1则得1,否则得0,最终得到的二进制为结果。
注意以下结果与&的不同
- 所有数字与0位或运算都得到数字本身;
- 所有数字与-1位或运算都得到-1;
- 所有正数与231-1位或运算都得到231-1,与-231位或都得到-231+数字;
- 所有负数与231-1位或运算都得到-1,与-231位或都得到数字本身;
public static void main(String[] args)
{
System.out.println("2147483647 : " + Integer.toBinaryString(2147483647));
System.out.println("-2147483648 : " + Integer.toBinaryString(-2147483648));
System.out.println("-1 : " + Integer.toBinaryString(-1));
System.out.println("0 : " + Integer.toBinaryString(0));
System.out.println("---------------------------------------------------------");
System.out.println("10 : " + Integer.toBinaryString(10));
System.out.println("1 : " + Integer.toBinaryString(1));
System.out.println("10|1 : " + Integer.toBinaryString(10|1) + "|" + (10|1));
System.out.println("10|-8: " + Integer.toBinaryString(10|-8) + "|" + (10|-8));
System.out.println("---------------------------------------------------------");
System.out.println("-10 : " + Integer.toBinaryString(-10));
System.out.println("-2 : " + Integer.toBinaryString(-2));
System.out.println("1 : " + Integer.toBinaryString(1));
System.out.println("-10|-2: " + Integer.toBinaryString(-10|-2) + "|" + (-10|-2));
System.out.println("-10|1 : " + Integer.toBinaryString(-10|1) + "|" + (-10|1));
System.out.println("---------------------------------------------------------");
System.out.println("10|-1: " + Integer.toBinaryString(10|-1) + "|" + (10|-1));
System.out.println("100|-1: " + Integer.toBinaryString(100|-1) + "|" + (100|-1));
System.out.println("2147483647|-1: " + Integer.toBinaryString(2147483647|-1) + "|" + (2147483647|-1));
System.out.println("-2147483648|-1: " + Integer.toBinaryString(-2147483648|-1) + "|" + (-2147483648|-1));
System.out.println("---------------------------------------------------------");
System.out.println("10|0: " + Integer.toBinaryString(10|0) + "|" + (10|0));
System.out.println("-10|0: " + Integer.toBinaryString(-10|0) + "|" + (-10|0));
System.out.println("2147483647|0: " + Integer.toBinaryString(2147483647|0) + "|" + (2147483647|0));
System.out.println("-2147483648|0: " + Integer.toBinaryString(-2147483648|0) + "|" + (-2147483648|0));
System.out.println("---------------------------------------------------------");
System.out.println("2147483647|-2147483648: " + Integer.toBinaryString(2147483647|-2147483648) + "|" + (2147483647|-2147483648));
System.out.println("-10|2147483647 : " + Integer.toBinaryString(-10|2147483647) + "|" + (-10|2147483647));
System.out.println("-123|2147483647 : " + Integer.toBinaryString(-123|2147483647) + "|" + (-123|2147483647));
System.out.println("10|2147483647 : " + Integer.toBinaryString(10|2147483647) + "|" + (10|2147483647));
System.out.println("-10|-2147483648 : " + Integer.toBinaryString(-10|-2147483648) + "|" + (-10|-2147483648));
System.out.println("-123|-2147483648 : " + Integer.toBinaryString(-123|-2147483648) + "|" + (-123|-2147483648));
System.out.println("10|-2147483648 : " + Integer.toBinaryString(10|-2147483648) + "|" + (10|-2147483648));
}
2147483647 : 1111111111111111111111111111111
-2147483648 : 10000000000000000000000000000000
-1 : 11111111111111111111111111111111
0 : 0
---------------------------------------------------------
10 : 1010
1 : 1
10|1 : 1011|11
10|-8: 11111111111111111111111111111010|-6
---------------------------------------------------------
-10 : 11111111111111111111111111110110
-2 : 11111111111111111111111111111110
1 : 1
-10|-2: 11111111111111111111111111111110|-2
-10|1 : 11111111111111111111111111110111|-9
---------------------------------------------------------
10|-1: 11111111111111111111111111111111|-1
100|-1: 11111111111111111111111111111111|-1
2147483647|-1: 11111111111111111111111111111111|-1
-2147483648|-1: 11111111111111111111111111111111|-1
---------------------------------------------------------
10|0: 1010|10
-10|0: 11111111111111111111111111110110|-10
2147483647|0: 1111111111111111111111111111111|2147483647
-2147483648|0: 10000000000000000000000000000000|-2147483648
---------------------------------------------------------
2147483647|-2147483648: 11111111111111111111111111111111|-1
-10|2147483647 : 11111111111111111111111111111111|-1
-123|2147483647 : 11111111111111111111111111111111|-1
10|2147483647 : 1111111111111111111111111111111|2147483647
-10|-2147483648 : 11111111111111111111111111110110|-10
-123|-2147483648 : 11111111111111111111111110000101|-123
10|-2147483648 : 10000000000000000000000000001010|-2147483638
位异或 ^
位异或,是将数字在二进制形式下,并且都补齐到32位,然后逐一对两个数的每一位进行比较,两个数字该位有一个为1另一个为0则得1,否则得0,最终得到的二进制为结果。
public static void main(String[] args)
{
System.out.println("2147483647 : " + Integer.toBinaryString(2147483647));
System.out.println("-2147483648 : " + Integer.toBinaryString(-2147483648));
System.out.println("-1 : " + Integer.toBinaryString(-1));
System.out.println("0 : " + Integer.toBinaryString(0));
System.out.println("---------------------------------------------------------");
System.out.println("10 : " + Integer.toBinaryString(10));
System.out.println("1 : " + Integer.toBinaryString(1));
System.out.println("10^1 : " + Integer.toBinaryString(10^1) + "|" + (10^1));
System.out.println("10^-8: " + Integer.toBinaryString(10^-8) + "|" + (10^-8));
System.out.println("---------------------------------------------------------");
System.out.println("-10 : " + Integer.toBinaryString(-10));
System.out.println("-2 : " + Integer.toBinaryString(-2));
System.out.println("1 : " + Integer.toBinaryString(1));
System.out.println("-10^-2: " + Integer.toBinaryString(-10^-2) + "|" + (-10^-2));
System.out.println("-10^1 : " + Integer.toBinaryString(-10^1) + "|" + (-10^1));
System.out.println("---------------------------------------------------------");
System.out.println("10^-1: " + Integer.toBinaryString(10^-1) + "|" + (10^-1));
System.out.println("100^-1: " + Integer.toBinaryString(100^-1) + "|" + (100^-1));
System.out.println("2147483647^-1: " + Integer.toBinaryString(2147483647^-1) + "|" + (2147483647^-1));
System.out.println("-2147483648^-1: " + Integer.toBinaryString(-2147483648^-1) + "|" + (-2147483648^-1));
System.out.println("---------------------------------------------------------");
System.out.println("10^0: " + Integer.toBinaryString(10^0) + "|" + (10^0));
System.out.println("-10^0: " + Integer.toBinaryString(-10^0) + "|" + (-10^0));
System.out.println("2147483647^0: " + Integer.toBinaryString(2147483647^0) + "|" + (2147483647^0));
System.out.println("-2147483648^0: " + Integer.toBinaryString(-2147483648^0) + "|" + (-2147483648^0));
System.out.println("---------------------------------------------------------");
System.out.println("2147483647^-2147483648: " + Integer.toBinaryString(2147483647^-2147483648) + "|" + (2147483647^-2147483648));
System.out.println("-10^2147483647 : " + Integer.toBinaryString(-10^2147483647) + "|" + (-10^2147483647));
System.out.println("-123^2147483647 : " + Integer.toBinaryString(-123^2147483647) + "|" + (-123^2147483647));
System.out.println("10^2147483647 : " + Integer.toBinaryString(10^2147483647) + "|" + (10^2147483647));
System.out.println("-10^-2147483648 : " + Integer.toBinaryString(-10^-2147483648) + "|" + (-10^-2147483648));
System.out.println("-123^-2147483648 : " + Integer.toBinaryString(-123^-2147483648) + "|" + (-123^-2147483648));
System.out.println("10^-2147483648 : " + Integer.toBinaryString(10^-2147483648) + "|" + (10^-2147483648));
}
2147483647 : 1111111111111111111111111111111
-2147483648 : 10000000000000000000000000000000
-1 : 11111111111111111111111111111111
0 : 0
---------------------------------------------------------
10 : 1010
1 : 1
10^1 : 1011|11
10^-8: 11111111111111111111111111110010|-14
---------------------------------------------------------
-10 : 11111111111111111111111111110110
-2 : 11111111111111111111111111111110
1 : 1
-10^-2: 1000|8
-10^1 : 11111111111111111111111111110111|-9
---------------------------------------------------------
10^-1: 11111111111111111111111111110101|-11
100^-1: 11111111111111111111111110011011|-101
2147483647^-1: 10000000000000000000000000000000|-2147483648
-2147483648^-1: 1111111111111111111111111111111|2147483647
---------------------------------------------------------
10^0: 1010|10
-10^0: 11111111111111111111111111110110|-10
2147483647^0: 1111111111111111111111111111111|2147483647
-2147483648^0: 10000000000000000000000000000000|-2147483648
---------------------------------------------------------
2147483647^-2147483648: 11111111111111111111111111111111|-1
-10^2147483647 : 10000000000000000000000000001001|-2147483639
-123^2147483647 : 10000000000000000000000001111010|-2147483526
10^2147483647 : 1111111111111111111111111110101|2147483637
-10^-2147483648 : 1111111111111111111111111110110|2147483638
-123^-2147483648 : 1111111111111111111111110000101|2147483525
10^-2147483648 : 10000000000000000000000000001010|-2147483638
位非 ~
位非是单目运算符,是将数字在二进制形式下,并且都补齐到32位,然后逐一对每一位进行运算,1则的0,0则得1,最终得到的二进制为结果。
public static void main(String[] args)
{
System.out.println("2147483647 : " + Integer.toBinaryString(2147483647));
System.out.println("~2147483647 : " + Integer.toBinaryString(~2147483647) + "|" + ~2147483647);
System.out.println("-2147483648 : " + Integer.toBinaryString(-2147483648));
System.out.println("~-2147483648 : " + Integer.toBinaryString(~-2147483648) + "|" + ~-2147483648);
System.out.println("-1 : " + Integer.toBinaryString(-1));
System.out.println("~-1 : " + Integer.toBinaryString(~-1) + "|" + ~-1);
System.out.println("0 : " + Integer.toBinaryString(0));
System.out.println("~0 : " + Integer.toBinaryString(~0) + "|" + ~0);
System.out.println("10 : " + Integer.toBinaryString(10));
System.out.println("~10 : " + Integer.toBinaryString(~10) + "|" + ~10);
System.out.println("-10 : " + Integer.toBinaryString(-10));
System.out.println("~-10 : " + Integer.toBinaryString(~-10) + "|" + ~-10);
System.out.println("-100 : " + Integer.toBinaryString(-100) );
System.out.println("~-100 : " + Integer.toBinaryString(~-100) + "|" + ~-100);
System.out.println("100 : " + Integer.toBinaryString(100) );
System.out.println("~100 : " + Integer.toBinaryString(~100) + "|" + ~100);
}
2147483647 : 1111111111111111111111111111111
~2147483647 : 10000000000000000000000000000000|-2147483648
-2147483648 : 10000000000000000000000000000000
~-2147483648 : 1111111111111111111111111111111|2147483647
-1 : 11111111111111111111111111111111
~-1 : 0|0
0 : 0
~0 : 11111111111111111111111111111111|-1
10 : 1010
~10 : 11111111111111111111111111110101|-11
-10 : 11111111111111111111111111110110
~-10 : 1001|9
-100 : 11111111111111111111111110011100
~-100 : 1100011|99
100 : 1100100
~100 : 11111111111111111111111110011011|-101