JAVA位运算和位运算的一些技巧

一、位运算

可以对整形数值的各个位进行操作

二、位运算符

2.1 位运算符共分为7种

>>(右移运算符)、<<(左移运算符)、>>>(不带符号右移,高位补0)、&(与运算符)、|(或运算符)、~(非运算符)、^(异或运算符)

2.2 >>(右移运算符)

  • 公式:操作数>>右移的位数

  • 举例:

  1. 37>>2
    37对应的二进制为:‭0000 0000 0000 0000 0000 0000 0010 0101‬
    右移两位:0000 0000 0000 0000 0000 0000 0000 1001
    结果等于:37>>2 ==> 9
  2. -8>>3
    因为操作数为负数,得如下思考(省略多余高位为0的二进制)
    -8的原码:1000 1000
    -8的反码:1111 0111
    -8的补码:1111 1000
    利用-8的补码右移三位:1111 1111
    补码转为原码(取反,+1):1000 0001
    结果等于:-8>>3 ==> -1

2.3 <<(左移运算符)

  • 公式:操作数<<左移的位数

  • 举例:

  1. 37<<2
    37对应的二进制为:‭0000 0000 0000 0000 0000 0000 0010 0101‬
    左移两位:0000 0000 0000 0000 0000 0000 1001 0100
    结果等于:37<<2 ==> 148
  2. -8<<3
    因为操作数为负数,得如下思考(省略多余高位为0的二进制)
    -8的原码:1000 0100
    -8的反码:1111 0111
    -8的补码:1111 1000
    利用-8的补码左移三位:1100 0000
    补码转为原码(取反,+1):1100 0000
    结果等于:-8<<3 ==> -64

2.4 >>>(不带符号右移,高位补0)

  • 公式:操作数>>>右移的位数

  • 举例:

  1. 37>>>2
    37对应的二进制为:‭0000 0000 0000 0000 0000 0000 0010 0101‬
    右移两位:0000 0000 0000 0000 0000 0000 0000 1001
    结果等于:37>>>2 ==> 9
  2. -8>>>3
    因为操作数为负数,得如下思考
    -8的原码:1000 ‭0000 ‭0000 ‭0000 ‭0000 ‭0000 ‭0000 1000
    -8的反码:1111 1111 1111 1111 1111 1111 1111 0111
    -8的补码:‭1111 1111 1111 1111 1111 1111 1111 1000‬
    利用-8的补码右移三位:0001 1111 1111 1111 1111 1111 1111 1111
    结果等于:-8>>>3 ==> 536870911

2.5 &(与运算符)

  • 运算技巧:两个数字同时为1,结果为1,其余为0。
  • 举例:
  1. 1 & 1 = 1;
  2. 9 & 3
    9的二进制表示为:0000 1001
    3的二进制表示为:0000 0011
    结果与运算: 0000 0001
    转为十进制为:1

2.6 |(或运算符)

  • 运算技巧:两个数字有一个为1,结果为1,其余为0。
  • 举例:
  1. 1 | 1 = 1;
  2. 1 | 0 =1
  3. 9 & 3
    9的二进制表示为:0000 1001
    3的二进制表示为:0000 0011
    结果或运算: 0000 1011
    转为十进制为:11

2.7 ~(非运算符)

  • 运算技巧:取反,0变1,1变0。
  • 举例:
  1. ~1 = 0
  2. ~0 = 1
  3. ~9
    9的二进制表示为:0000 1001
    结果非运算: ‭1111 1111 1111 1111 1111 1111 1111 0110
    运算结果为负数,转原码:1000 0000 0000 0000 0000 0000 0000 1010
    转为十进制为:-10

2.8 ^(异或运算符)

  • 运算技巧:相同为0,相异为1.
  • 举例:
  1. 1 ^ 1 = 0
  2. 1 ^ 0 = 1
  3. 4 ^ 3
    4的二进制表示为:0000 0100
    3的二进制表示为:0000 0011
    结果异或运算: ‭0000 0111
    转为十进制为:7

异或有如下特性:
1、可以理解为不进位加法:
1 + 1 = 0
1 + 0 = 1
0 + 1 = 1
0 + 0 = 0
2、具有交换律,可以任意交换因子的位置,结果不变
A ^ B ^ A == A ^ A ^ B
3、具有结合律
A ^ B ^ A = A ^ (B ^ A)
4、对于任何数,同自己求异或为0,同0求异或为自己
X ^ X = 0
X ^ 0 = X
5、自反性,连续和同一个因子异或结果为自己
A ^ B ^ B = A ^ 0 = A
6、求负整数的反码
A ^ -1

与或非异或关系表

ABA & BA 或 B~AA ^ B
000010
010111
100101
111100

三、判断一个整数是奇数还是偶数

任意一个数 X & 1 = 1时,为奇数

Created with Raphaël 2.2.0 输入33 33的二进制与1的二进制 reset = 1? 奇数 偶数 yes no

十进制33的二进制为: 0010 0001
  0010 0001
 &
  0000 0001
————————
  0000 0001

结果:1

任意一个数 X & 1 = 0时,为偶数

十进制32的二进制为: 0010 0000
  0010 0000
 &
  0000 0001
————————
  0000 0000

结果:0

四、判断一个整数某二进制位,是1还是0

第一种:对整数的从右到左依次编号,比如求n位,为0还是1。对1进行左移n-1位,然后进行运算,最后结果在进行右移n-1位

十进制36的二进制为: 0010 0100 ,求第三位为1还是0
1左移2位 0000 0100
  0010 0 1 00
 &
  0000 0 1 00
————————
  0000 0 1 00

结果:4
对结果为进行右移2位
8对应的二进制:0000 0400
8>>2 = 1

即36的对应的二进制第三位为:1

五、利用位运算进行交换整形变量的值

		int x = 99;
		int y = 87;
		
		x = x ^ y;
		y = x ^ y; //y = x ^ y ^ y ==> y = x
		x = x ^ y; //x = x ^ y  ^ x ==> x = y
		System.out.println("x="+x);
		System.out.println("y="+y);

输出结果:
x=87
y=99

六、不用判断语句,求整数的绝对值

  1. 对于任意一个正整数n或者负整数n,右移31位结果必为0或==-1==。
  2. n异或上n右移31位的结果(n ^ (n >> 31) ),如果为n为正整数结果 = n,如果为n 为负整数结果为n的反码
  3. n无符号右移31位,结果为如果为n为正整数结果 0,如果为n 为负整数结果为1
  4. 上述 2和3做和就可以算出绝对值:(n ^ (n >> 31)) + n>>>31

例如:
整数: -32
公式拆解:n >> 31

  • 对应二进制位(补码):‭1111 1111 1111 1111 1111 11111 1110 0000
  • 右移31位(补码):1111 1111 1111 1111 1111 11111 1111 1111
  • 转为原码:1000 0000 0000 0000 0000 0000 0000 0001
  • 结果为 n >> 31 = -1

公式拆解:n ^ (n >> 31)
-32 对应补码:1111 1111 1111 1111 1111 11111 1110 0000
   ^(异或)
-1对应补码: 1111 1111 1111 1111 1111 11111 1111 1111
       ————————————————————
       0000 0000 0000 0000 0000 000 0001 1111
结果为:31
即为 -32的反码。

公式拆解:n>>>31
(反码和补码结果差1)
-32 对应补码:1111 1111 1111 1111 1111 11111 1110 0000
-32>>>31 = 0000 0000 0000 0000 0000 0000 0000 0001
n>>>31 = 1;

综上所述:
(n ^ (n >> 31)) + n>>>31 = 31+ 1 = 32.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值