二进制和位运算
目录
简介
以前对于位运算, 二级制了解的比较少. 这里统一记录一下使用和理解. 主要使用 python 做示范.
内容
进制
2 进制:逢 2 进 1
8 进制:逢 8 进 1
16 进制:逢 16 进 1
在 C 程序中的表示 (python 中也一样):
0b101 /*2进制 0b开头*/
0115 /*8进制 0开头*/
0xFFF /*16进制 0x开头*/
转换十进制方法: 个位直接加,十位是进制数的 1 次方,百位是进制数的 2 次方,高位以此类推即可0b101 = 1 + 0*2 + 1*2*2
0115 = 5 + 1*8 + 1*8*8
0xFAF = 15 + 10*15 + 15*15*15
位运算符
我其实用的不是特别多,见的也不多。但是在很多的官方案例中出现过,比如 python 人脸识别中的跳出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
先把所有的运算符列出来:
<< #左移
>> #右移
| #位或
& #位与
^ #位异或
~ #非
<< #左移
将所有的0和1的位置进行左移,移位之后将空位补0
左移操作相当于乘以2**n,以5 << 3 为例,相当于5(2*3),结果为40
0b101 变成了 0b101000
# 一个int是4个字节,一个字节是8位(bit),它存储的大小就是32位
# 如果加了0,超出了32位边界,那么就是溢出了
>> #右移
将所有的0和1的位置进行右移(直接舍弃),空位正数补0,负数补1
右移操作相当于除以2**n,8 >> 3 相当于8/(2**3)=1
| #位或
0b110 | 0b101 #输出7,即0b111
只要有一位有1就为1,可以用在综合条件
& #位与
0b110 & 0b011 #输出2,即0b010
相同的位才为1,可以用在linux权限
^ #位异或
0b1010 ^ 0b1111 #输出5,即0b0101
异或常用于将所有的位反转,相同的位置是0,否则其他的位置变1,
~ #非
~0b101 #输出2,即0b010
这个是单独运算的,直接就把所有的反转了
理解 cv2.waitKey(1) & 0xFF == ord('q')
- 查看 python 结果
$ python
Python 3.6.3 (default, Oct 16 2017, 17:26:31)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print(ord('q'))
113
- 查看键盘 q 对应的数字是多少
#include <stdio.h>
int main()
{
char i;
scanf("%c", &i);
printf("i = %d \n", i);
return 0;
}
Launching: '/Users/user/kent/c/a.out'
Working directory: '/Users/user/kent/c'
1 arguments:
argv[0] = '/Users/user/kent/c/a.out'
q
q = 113
Process exited with status 0
- 那么推算如下
cv2.waitKey(1) & 0xFF == ord('q')
cv2.waitKey(1) & 0xFF == 113
0xFF代表了你键盘上的所有按键都能匹配到(包括一些系统自己拓展的特殊按键)。
当我们按了`q`键,cv2.waitKey(1)得到的就是113的二进制,和0xFF匹配出来的结果就是二进制的113,在任何系统上转换为十进制,都会和右边的十进制113相等。
避免了bug