位运算(Java)

1.位运算基础

Java中常用位运算符号包括:

操作符名称描述
&如果对应位都是1,则结果为1,否则为0
|如果对应位都是0,则结果为0,否则为1
^异或如果对应位相同,则结果为0,否则为1
~取反对运算符翻转每一位,即0变成1,1变成0
<<左移按位左移运算符。左操作数按位左移右操作数指定的位数。
>>右移按位右移运算符。左操作数按位右移右操作数制定的位数。
>>>无符号右移按位右移补零操作符。在>>之后,移动的得到的空位以零填充。

补充:无符号右移
10进制转二进制的时候,因为二进制数一般分8位、 16位、32位以及64位 表示一个十进制数,所以在转换过程中,最高位会补零。
计算机中负数使用二进制的补码表示。10进制转2进制的是源码,源码取反是反码,反码加1是补码。

A = 0011 1100
B = 0000 1101
------------------
A & B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~ A = 1100 0011
A << 2 = 1111 0000
A >> 2 = 1111
A >>> 2 = 0000 1111
------------------
C = 1111 1111	// (补码的-1)
C >>> 4 = 0000 1111

2. 常考技巧

2.1 基本表示

题目一:常用计算和位运算

  1. 取模运算转化成位运算 (在不产生溢出的情况下)
a % (2^n)
a & (2^n - 1) 
  1. 乘法运算转化成位运算 (在不产生溢出的情况下)
a * (2^n)
a < < n 
  1. 除法运算转化成位运算 (在不产生溢出的情况下)
a / (2^n) 
a >> n 
// 例: 12/8 == 12>>3 
  1. 除以2的余数
a % 2 
a & 1
  1. 相反数
(~x+1)

题目二:判断一个数 x 的奇偶性

n&1 == 1 ? "奇数" : "偶数"

如果 x 是奇数,则最低位是1,。注意是与,由于1的前面都是0,所以 x 的前面位无论是几,和0与都是0。

题目三:取int型变量 x 的第k位 (k=0,1,2……sizeof(int))

(x>>k) & 1

题目四:将int型变量a的第k位清0

x = x &~(1 << k) 

题目五:整数的平均数

对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的。

int average(int x, int y) {    
    return (x&y)+((x^y)>>1); 
} 

题目六:计算绝对值

int abs( int x ) { 
int y ; 
y = x >> 31 ; 
return (x^y)-y ;        //or: (x+y)^y 
} 

2.2 去掉 x 的最后一个1

x = 1100
x-1 = 1011
x & (x-1) = 1000

题目一:用O(1)时间检测整数n是否是2的幂次.

思路:2的幂次满足两个条件

  • n > 0
  • n的二进制中只有一个1
    用 x&(x-1) 将最后一个1去掉,如果是2的幂次,则结果为0.

题目二:计算在一个 32 位的整数的二进制表示中有多少个 1.

思路:
循环使用 x&(x-1) 去掉最后一个1,计算总共消去了多少次即可。

题目三:将整数A转换为B,需要改变多少个bit位.

思路:
如果A和B在第 i 个位上相等,则不需要改变这个bit位;如果在第 i 位上不相等,则需要改变这个bit位;所以问题转化为了A和B有多少个bit位不相同。联想到位运算有一个异或操作,相同为0,不同为1,所以问题转化为了计算A和B异或之后有多少个1.

2.3 使用二进制进行子集枚举

题目一:给定一个含不同整数的集合,返回其所有的子集

题目:如果 S = [1,2,3],有如下的解:[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2] ]
思路:

题目二:不用临时变量交换两个数

A = 5;
B = 12;
A = A^B;	
B = B^A;	// =B ^ (A^B)  =A.
A = A^B;	// =(A^B) ^ A  =B.

参考
[1] Java位运算原理及使用讲解
[2] 位运算——强大得令人害怕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值