一、位运算
在现代计算机中,所有数据都以二进制形式存储,即 0 和 1 两种状态。计算机对二进制数据进行的运算(如加、减、乘、除)被称为位运算,即对二进制数的每一位进行操作的运算。
所以,与直接使用 +、-、*、/ 运算符相比,合理运用位运算可以显著提高代码在机器上的执行效率。
二、位运算概览
| 符号 | 描述 | 运算规则 | |
|---|---|---|---|
| & | 与 | 两个位都为1时,结果才为1 | |
| 或 | 两个位都为0时,结果才为0 | ||
| 异或 | 两个位相同为0,相异为1 | ||
| ~ | 取反 | 0变1,1变0 | |
| << | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0 | |
| >> | 右移 | 各二进位全部右移若干位,高位补0或符号位补齐 |
一、位与
0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1
总结:只有两位同时为1时,结果才为1,否则结果为0。
例如:3 & 5 即 0000 0011 & 0000 0101 = 0000 0001,因此 3 & 5 的值为1。
二、位或
0 | 0 = 0 0 | 1 = 1 1 | 0 = 1 1 | 1 = 1
总结:只要有一个为1,其值为1。
例如:3 | 5 即 0000 0011 | 0000 0101 = 0000 0111,因此 3 | 5 的值为7。
注意:负数按补码形式参与按位或运算。
三、异或
0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0
总结:相应位相同为0,相异为1。
四、取反
~1 = 1111 1110 ~0 = 1111 1111
总结:将 0 变 1,1 变 0。
五、左移
定义:将一个运算对象的各二进制位全部左移若干位,高位丢弃,低位补0。
例如,设 a = 1010 1110,a = a << 2 将 a 的二进制位左移2位、右补0,即得 a = 1011 1000。
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
六、右移
定义:将一个数的各二进制位全部右移若干位,高位补0或补符号位,右边丢弃。
例如,a = a >> 2 将 a 的二进制位右移2位,左补0 或补符号位,具体取决于数的正负。
操作数每右移一位,相当于该数除以2。
题目:二进制转码问题
问题描述
小C在学习二进制运算,他了解到每个非负整数都有其二进制表示。例如,整数 5 可以被表示为二进制 "101",整数 11 可以被表示为二进制 "1011",并且除了 N = 0 外,任何二进制表示中都不含前导零。
二进制的反码表示是将每个 1 变为 0,每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"。现在小C想知道,给定一个十进制数 N,它的二进制反码对应的十进制数是多少。
测试样例
样例1:
输入:
N = 5
输出:2
样例2:
输入:
N = 10
输出:5
样例3:
输入:
N = 0
输出:1
思路
-
十进制转二进制:
- 使用栈来存储每次除以2的余数,这样可以从低位到高位构建二进制数。
- 代码中使用了
while N > 0循环,每次取N除以2的余数,并将余数压入栈s中,然后将N更新为N // 2(整除)。
-
构建二进制字符串:
- 接着使用
while len(s) > 0循环,将栈中的元素依次弹出并拼接成字符串binstring,这样就得到了N的二进制表示。
- 接着使用
-
补码操作:
- 代码中的补码操作实际上是将二进制数中的
1替换为2,0替换为1,然后再将所有的2替换为0。这个过程实际上并没有改变二进制数的值,只是进行了一次无意义的字符替换。
- 代码中的补码操作实际上是将二进制数中的
-
将补码字符串转换为十进制:
- 最后,将得到的补码字符串
binstring_comple_3转换为十进制数binstring_comple_ten并返回。
- 最后,将得到的补码字符串
代码
def solution(N):
#十进制转二进制
#1.栈实现;2.bin()
#binnum = bin(N)
#return binnum
#bin带二进制0b前缀,可用[2:]舍去前缀
#定义栈
if N == 0:
return 1
s = []
binstring = ''
while N > 0:
#余数进栈
rem = N % 2
s.append(rem)
N = N // 2
while len(s) > 0:
#元素全部出栈即为所求二进制数
#栈(后进先出),pop()从栈s中移除并返回最后一个元素
binstring = binstring + str(s.pop())
#互换需要中间元素
binstring_comple_1 = binstring.replace('1','2')
binstring_comple_2 = binstring_comple_1.replace('0','1')
binstring_comple_3 = binstring_comple_2.replace('2','0')
binstring_comple_ten = int(binstring_comple_3, 2)
return binstring_comple_ten