java 常见位运算

java源码中很多都用到位运算,粗浅的讨论一下这些位运算的用处。

获取比N大的2的幂数

n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
n++;

取至hashmap 的tableSizeFor方法。

我们先看一些2的幂数有什么特征。 按照二进制查看数值,除首位1之外 其他的后面都为0的 为2的幂数(常规)

10(2) 100(4) 1000(8) 10000(16) 100000(32)

那么最接近2的幂数的是哪些呢

1(1) 11(3) 111(7) 1111(15) 11111(31)

那么全为1的数值最接近2的幂数,现在看一下方法怎么将一个值变为比它大的最接近2幂数值

上面的方法只支持int类型的2幂数获取,因为int使用二进制表示只有32位,其中第一位符号位 0表示正数 1表示负数

取任意正数,除0外,那么它的值一定是1XXXXXX ,X位数小于等于30可能是1也可能是0在这个位运算中不重要。

n |= n >>> 1; 运行的时候

1XXXXXX

01XXXXX┆X 位移 首位补零,末尾被截取

计算结果为11XXXXX

n |= n >>> 2;

11XXXXX

0011XXX┆XX

计算为1111XXX

由于第一次运算的时候只能确保第一位是1,第一次位移一次那么就能确保前两位是1

第二次位移在确保前两位为1的基础上,位移两位,那么前四位一定都是1,

以次类推就能确保将1XXXXXX后面的X都变为1

当回去到1111111值是 加上1 = 10000000 这就是一个2的幂数

此方法就是将首位后面的值都变为1,然后最终结果加1 这就成了比当前值大的2的幂数。

在大部分解析文档的时候,都会用到下面的位运算

b[0] = n&0xFF b[1] =n>>>8&0xFF b[2]=n>>>16&0xFF b[3] = n>>>24&0xFF

n=b[0] & 0xFF | (b[1] & 0xFF) << 8 | (b[2] & 0xFF) << 16 | (b[3] & 0xFF) << 24

正常情况下文档结构都是二进制的byte数组组成,因为int 32位 byte是8位的

因此一般使用长度为4的byte数组分别装int值

byte[0] = int值1-8位 byte[1] = int值9-16位 byte[2] = int值17-24位 byte[3] = int值25-32位

0xFF = 255 = 11111111 八位数全部为1的值

n&0xFF 等效于

32-25位|24-17位|16-9位|8-1位| & 11111111 == 8-1位的值,32-9位的由于 0xFF的前面位数都是0因此 与 运算后都是0 结果就是 8-1位的值

n>>>8 & 0xFF 等效于

8位0|原32-25位|原24-17位|原16-9位┆原8-1位 相当于把原先的1-8位截取了,用9-16补齐,与 运算后就是9-16的值

以此类推b[0] = n的1-8位值 b[1] = n的9-16位值 b[2] = n的17-24位值 b[3] = n的25-32位值

根据以上的编码,那我们就能将byte解码

b[0] & 0xFF = 32-9位0|8-1值 的值

(b[1] & 0xFF)<<8 = 32-17位0|16-9的值|8-1位0 的值

(b[2] & 0xFF)<<16 = 32-25位0|24-17位的值|16-1位0 的值

(b[3] & 0xFF)<<24 = 32-25的值|24-1位的0 的值

将四个数值进行或运算 == 32-25的值|24-17位的值|16-9的值|8-1值 == n

转载于:https://my.oschina.net/u/3704615/blog/1557079

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值