我们已经知道计算机是基于二进制实现操作计算机的源头是二进制,一些你不知道的知识。,我们来看看,计算机语言中针对二进制的位操作。这里的位操作,也叫作位运算,就是直接对内存中的二进制位进行操作。
其中二进制位操作主要分为:移位操作和逻辑操作。常见的二进制移位操作包括向左移位和向右移位,二进制逻辑操作有“或”“与”“异或”。下面我们一一来看。
向左移位在不考虑数字溢出的情况下,二进制111101向左移一位,就是在末尾添加一位0,因此111101就变成了1111010.
什么是数字溢出?定义:二进制数的位数超过了系统所指定的位数。
现在的操作系统至少支持32位的整型数字,而1111010远远没有超过32位,所以不会发生溢出。
如果进行左移操作的二进制已经超出了32位,左移后数字就会溢出,需要将溢出的位数去除。
在这个例子中,如果将1101010换算为十进制,就是106,你有没有发现,106正好是53的2倍。所以,我们可以得出一个结论:二进制左移一位,其实就是将数字翻倍。
向右移位二进制110101向右移一位,就是去除末尾的那一位,因此110101就变成了11010(最前面的0可以省略)。我们将11010换算为十进制,就是26,正好是53除以2的整数商。所以二进制右移一位,就是将数字除以2并求整数商的操作。
Python实现移位操作下面我们来看看,用代码如何进行移位操作。
左移:
左移运算符mn表示把m左移n位。在左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。比如:
000010102=00101000
100010103=01010000
Python代码【结果有点不一样】:bin(int('0b00001010',2)2).replace('0b','').zfill(8)'00101000'bin(int('0b10001010',2)3).replace('0b','').zfill(8)'10001010000'bin(-int('0b00001010',2)2).replace('0b','').zfill(8)'-0101000'右移:
右移运算符mn表示把m右移n位。在右移n位的时候,最右边的n位将被丢弃。但右移时处理最左边位的情形要复杂一点。如果数字是一个无符号树值,则用0填补最左边的n位;如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说,如果数字原先是一个正数,则右移之后在最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1。
下面是对两个8位有符号数进行右移的例子:
000010102=00000010100010103=11110001Python代码【结果有点不一样】:bin(int('0b10001010',2)2).replace('0b','').zfill(8)'00100010'bin(int('0b10001010',2)3).replace('0b','').zfill(8)'00010001'bin(-int('0b10001010',2)3).replace('0b','').zfill(8)'-0010010'位的“或”二进制的“1”和“0”分别对应逻辑中的“真”和“假”,因此可以针对位进行逻辑操作。
逻辑“或”的意思是,参与操作的位中只要有一个位是1,那么最终结果就是1,也就是“真”。如果我们将二进制110101和100011的每一位对齐,进行按位的“或”操作,就会得到110111。
位的“与”同理,我们也可以针对位进行逻辑“与”的操作。“与”的意思是,参与操作的位中必须全都是1,那么最终结果才是1(真),否则就为0(假)。如果我们将二进制110101和100011的每一位对齐,进行按位的“与”操作,就会得到100001。
位的“异或”逻辑“异或”和“或”有所不同,它具有排异性,也就是说如果参与操作的位相同,那么最终结果就为0(假),否则为1(真)。所以,如果要得到1,参与操作的两个位必须不同,这就是此处“异”的含义。我们将二进制110101和100011的每一位对齐,进行按位的“异或”操作,可以得到结果是10110。