位运算的巧妙应用
Android 中的位运算应用了解一下~
位运算
我们先了解一下 4种 最基本的二进制位运算
|
或运算( OR )
按规则 Y | 1 = 1
, Y | 0 = Y
运算
1 | 10010101 10100101 |
&
与运算( AND )
按规则 Y = 1
时 Y & 1 = 1
, Y=*
时 Y & 0 = 0
运算
1 | 10010101 10100101 |
^
异或( XOR )
按位不同为1,相同为0
1 | 10011101 10010101 |
~
非( NOT )
按位取反
1 | ~ 10011101 10010101 |
下面是逻辑运算表
bit 1 | bit 2 | OR | AND | XOR |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 0 |
掩码运算
现在有这样一段代码:
1 | public static final int FLAG_FOCUSABLE = 0X0001; // 0001 |
mFlags
记录了某些状态位,如果想向 flags
上添加一个状态 FLAG_ENABLE
,可以这样做 :
1 | // 向mFlags上添加一个标识位 |
检查flags
是否含有 FLAG_ENABLE
:
1 | boolean containEnableFlag; |
移除 flags
中的 FLAG_ENABLE
:
1 | flags &= ~FLAG_ENABLE; // flags = 0001 |
这几种操作方式为掩码运算,总结有以下几种方式
释义 | 运算 |
---|---|
设置或覆盖标志位 | flags Ι flagBit |
移除标志位 | flags & ~flagBit |
检查是否含有标志位 | (flags & flagBit) == flagBit |
标志位取反 | ~flags |
掩码运算并不直观,也不容易理解,所以在编程时并不推荐使用,但是如果考虑性能要求的话,使用掩码运算还是很划算的。
在Android 中的应用
View 类中可以设置其是否可见,可点击等,
1 | setFocusable(focusable); |
查看 View 的源代码片段
1 | /** |
可以看到 mViewFlags
记录 View 的 states,当调用 setFocusable()
, setClickable()
时,实际上是调用 setFlags()
来设置 mViewFlags
的值,像这种 掩码运算 的实际应用在 Android FrameWork 层很多地方都可以看到
Permissions on linux
在终端键入 ls -l
,会看到类似这样的输出结果
1 | -rw-rw-r--@ 1 septenary staff 1158 2 27 14:05 Readme.txt |
第一列由 d rwx rwx rwx 这种形式构成, d 标识文件夹,rwx 代表用户或用户组的 read write excute 权限,其中
1 | r=4; // 0100 |
如果想要更改 Readme.txt 文件 为可写、可读、可执行,键入
1 | chmod 777 ./Readme.txt |
此处的 777 即为 r + w + x
,用二进制运算表示 就是 0100 | 0010 | 0001
变量置换
有变量 a = 4; b = 7
, 将 a
,b
值互换,通常这么写:
1 | int a = 4; |
利用 异或^
运算可以这么写
1 | int a = 4; |
这种方式省去了 temp
32个字节的内存消耗,且计算更快