位运算实践

132 阅读2分钟

前言

在实际业务中遇到了位运算,在此记录实际业务中的使用方式。如果运用位运算熟练,可以减少运行开销,优化代码算法。

一、什么是位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。

二、位操作符

既然有位运算,肯定就涉及到操作符,跟加减乘除一样,认识下位操作符。

操作符号
&
|
异或
取反~
左移<<
右移>>

认识完操作符当然就是实践了。

三、入门实践

我们以6(0110)12(1100)作为接下来的例子

1、与(&):两个都为1就是1,否则为0

0110
1100
----
0100 = 4

2、或(|):两个都为0就是0,否则为1

0110
1100
----
1110 = 14

3、异或(^):两个相同就为0,否则为1

0110
1100
----
1010 = 10

4、取反(~):0为1,1为0

~0110 = -7

5、左移(<<):向左移位,低位补零,高位舍弃

0110 << 1 = 1100 = 12

6、右移(>>):向右移位,无符号高位补 0,有符号高位补符号位

0110 >> 1 = 0011 = 3

四、进阶实践

在最近接手的需求梳理代码过程中,有这样实现每日登陆/签到的标记,减少数据库的数据插入。

maskday1<<daymask | 1 << daybit
012210
2246110
638141110
:::::
53687091029536870912107374182200111111111111111111111111111110
1073741822301073741824214748364601111111111111111111111111111110
2147483646312147483648429496729411111111111111111111111111111110

我们知道一个月最多不会超过31天,所以用int32为记,从右到左开始,除开第一个0,依次往后,1代表签到过,0代表未签到。上表中,mask从零开始计数,根据日期号数增加,mask等于前一天的mask | 1<<day,再去运算当日的mask | 1 << day,就可以标记当日的签到状态。用年月(eg:202112)keyvaluemask,每次只需要在数据库更新mask的值即可。

五、尾声

当然,位运算的应用方式还有很多,推荐看这里。

知乎