(已废弃)Java位运算(位逻辑,位左移,位右移运算符)

参考新文一文搞明白位运算、原码、反码、补码
此文为32位二进制
连续的32位容易混乱,我用8位一组的方式分割

注意事项

要想看懂这篇文章,必须要知道什么是原码,反码,补码(二进制数)
请参考-1的32位二进制为什么是11111111 11111111 11111111 11111111

Java中Integer值域

1
2
3
System.out.println(Integer.MAX_VALUE);//2147483647=2^31-1

System.out.println(Integer.MIN_VALUE);//-2147483648=-(2^31)

Java二进制转十进制

1
System.out.println(Integer.valueOf("101",2));// 5

Java十进制转二进制

1
System.out.println(Integer.toBinaryString(5));// 101

Java位逻辑运算符

&

&使用说明

两位都为1 结果才是1

正&正

42&9=8

00000000 00000000 00000000 0010101042的补码
00000000 00000000 00000000 000010019的补码
42的补码&9的补码=8的补码
00000000 00000000 00000000 000010008的补码

正&负

42&-9=34

00000000 00000000 00000000 0010101042的补码
00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
42的补码&-9的补码=34的补码
00000000 00000000 00000000 0010001034的补码

负&负

-8&-111=-112

00000000 00000000 00000000 000010008的补码
10000000 00000000 00000000 00001000-8的原码
11111111 11111111 11111111 11110111-8的反码
11111111 11111111 11111111 11111000-8的补码
00000000 00000000 00000000 01101111111的补码
10000000 00000000 00000000 01101111-111的原码
11111111 11111111 11111111 10010000-111的反码
11111111 11111111 11111111 10010001-111的补码
-8的补码&-111的补码=-112的补码
11111111 11111111 11111111 10010000?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 10001111?的反码
10000000 00000000 00000000 01110000?的原码
00000000 00000000 00000000 01110000-?的原码=112的补码,所以?的补码=-112的补码

|

|使用说明

两位其中一个为1 结果就是1

正|正

42|9=43

00000000 00000000 00000000 0010101042的补码
00000000 00000000 00000000 000010019的补码
42的补码|9的补码=43的补码
00000000 00000000 00000000 0010101143的补码

负|正

-25|11=-17

00000000 00000000 00000000 0001100125的补码
10000000 00000000 00000000 00011001-25的原码
11111111 11111111 11111111 11100110-25的反码
11111111 11111111 11111111 11100111-25的补码
00000000 00000000 00000000 0000101111的补码
-25的补码|11的补码=-17的补码
11111111 11111111 11111111 11101111?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 11101110?的反码
10000000 00000000 00000000 00010001?的原码
00000000 00000000 00000000 00010001-?的补码=17的补码,所以?的补码=-17的补码

^

^使用说明

两位不相同 结果才是1

正^正

42^9=35

00000000 00000000 00000000 0010101042的补码
00000000 00000000 00000000 000010019的补码
42的补码^9的补码=35的补码
00000000 00000000 00000000 0010001135的补码

负^正

-42^9=-33

00000000 00000000 00000000 0010101042的补码
10000000 00000000 00000000 00101010-42的原码
11111111 11111111 11111111 11010101-42的反码
11111111 11111111 11111111 11010110-42的补码
00000000 00000000 00000000 000010019的补码
-42的补码^9的补码=-33的补码
11111111 11111111 11111111 11011111?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 11011110?的反码
10000000 00000000 00000000 00100001?的原码
00000000 00000000 00000000 00100001-?的补码=33的补码,所以?的补码=-33的补码

~

~使用说明

所有位都取反

~负

~-9=8

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
~-9的补码=8的补码
00000000 00000000 00000000 000010008的补码

Java位左移,位右移运算符

左移只有<< 没有<<<
右移有>> 也有>>>

>>>>>的区别

  • 正数时无区别,都补0
  • 负数时,>>补1,>>>补0

<<位左移

<<使用说明

x<<n 表示x二进制数(补码)向左移动n位,左边去除n位,右边补n个0

正<<1

9<<1 = 18

00000000 00000000 00000000 000010019的补码
9的补码<<1=18的补码
00000000 00000000 00000000 0001001018的补码

正<<3

9<<3 = 72

00000000 00000000 00000000 000010019的补码
9的补码<<3=72的补码
00000000 00000000 00000000 0100100072的补码

负<<1

-9<<1 -18

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
-9的补码<<1=-18的补码
11111111 11111111 11111111 11101110?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 11101101?的反码
10000000 00000000 00000000 00010010?的原码
00000000 00000000 00000000 00010010-?的补码=18的补码,,所以?的补码=-18的补码

负<<3

-9<<3 -72

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
-9的补码<<3=-72的补码
11111111 11111111 11111111 10111000?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 10110111?的反码
10000000 00000000 00000000 01001000?的原码
00000000 00000000 00000000 01001000-?的补码=72的补码,所以?的补码=-72的补码

>>位右移

x>>n
表示x>0 x二进制数(补码)向右移动n位,右边去除n位,左边补n个0
表示x<0 x二进制数(补码)向右移动n位,右边去除n位,左边补n个1

>>使用说明

x>>n = x/2^n(0<n<32 且为整数)
如果x>0 对结果取整
如果x<0 对结果有小数就进1

正>>1

9>>1 = 9/2^1 = 9/2 = 4 对结果取整

00000000 00000000 00000000 000010019的补码
9的补码>>1=4的补码
00000000 00000000 00000000 000001004的补码

正>>3

9>>3 = 9/2^3 = 9/(2*2*2) = 1 对结果取整

00000000 00000000 00000000 000010019的补码
9的补码>>3=1的补码
00000000 00000000 00000000 000000011的补码

负>>1

-9>>1 = -9/2^1 = -9/2 = -5 对结果有小数就进1

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
-9的补码>>1=-5的补码
11111111 11111111 11111111 11111011?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 11111010?的反码
10000000 00000000 00000000 00000101?的原码
00000000 00000000 00000000 00000101-?的补码=5的补码,所以?的补码=-5的补码

负>>3

-9>>3 = -9/2^3 = -9/(2*2*2) = -2 对结果有小数就进1

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
-9的补码>>3=-2的补码
11111111 11111111 11111111 11111110?的补码(因为第一位是1 所以?<0)
11111111 11111111 11111111 11111101?的反码
10000000 00000000 00000000 00000010?的原码
00000000 00000000 00000000 00000010-?的补码=2的补码,所以?的补码=-2的补码

>>>位右移

>>>使用说明

x>>n
表示x不论正负 x二进制数(补码)向右移动n位,右边去除n位,左边补n个0

正>>>1

正>>1相同

正>>>3

正>>3相同

负>>>1

-9>>>1

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
-9的补码>>>1=2147483643
01111111 11111111 11111111 11111011?的补码(因为第一位是0 所以?>0)
进制转换网址 2147483643

正>>>3

-9>>>1

00000000 00000000 00000000 000010019的补码
10000000 00000000 00000000 00001001-9的原码
11111111 11111111 11111111 11110110-9的反码
11111111 11111111 11111111 11110111-9的补码
-9的补码>>>3=536870910
00011111 11111111 11111111 11111110?的补码(因为第一位是0 所以?>0)
进制转换网址 536870910