应用案例
现有一个整数,将该整数转化为二进制形式,并统计二进制中1的个数(如果是负数,按补码统计1的个数)
涉及知识点讲解
进制介绍
在计算机中,有四种进制,分别是 2进制、8进制、10进制和16进制。具体内容如下所示:
进制类型 | 组成 | 代码格式 |
---|---|---|
2进制 | 由2个数字组成,有0 和 1 | 0b101 |
8进制 | 由8个数字组成,有0,1,2,3,4,5,6,7 | 0o127 |
10进制 | 有10个数字组成,有0,1,2,3,4,5,6,7,8,9 | 258 |
16进制 | 有16个数字组成,有0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f (字母不区分大小写, a至f分别代表10,11,12,13,14,15) | 0xff、0Xff、0XFF |
进制转换
Python中常用的内置进制转换函数如下所示:
- bin(x): 将 x 转换为2进制;
- oct(x): 将 x 转换为8进制;
- int(x, base=10): 将 x 转为 10 进制;
- hex(x): 将 x 转为 16 进制;
原码、反码、补码介绍
计算机使用一定的编码方式对数据进行存储。原码、反码、补码是机器存储一个具体数字的编码方式。具体使用方式整理如下:
- 正数的原码、反码、补码都相同;
- 负数的反码在原码的基础上保持符号位不变,其余位取反;
- 负数的补码在反码的基础上+1;
eg:
+1 | -1 | |
---|---|---|
原码 | 0000 0001 | 1000 0001 |
反码 | 0000 0001 | 1111 1110 |
补码 | 0000 0001 | 1111 1111 |
位运算规则
含义 | Python表示 | 规则说明 |
---|---|---|
按位与 | a & b | 同时为1,则为1 |
按位或 | a | b | 有1则为1 |
按位异或 | a ^ b | 相同为0,不同为1 |
按位取反 | ~a | 0变1,1变0 |
左移 | a << b | a × 2**b |
右移 | a >> b | a / 2**b |
解法1
思路分析
首先需将整数转换成二进制,转换时考虑正整数和负整数两种情况:
- 如果是正整数,直接转换成二进制即可;
- 如果是负整数,需求出该数对应的补码,以便后期解题;
难点:Python中如何让对一个负整数求补码?
等全部转换成二进制后,开始统计1的个数,解法1为:将该二进制数转化为字符串,然后对该字符串进行遍历,如果等于1,计数器+1;
代码实现
def oneCount1(n):
# 使用Python内置bin函数转化成二进制;
print(bin(n))
if n < 0:
# 下一行语句是 按位与运算求一个负数的补码
# 表示先将符号两边转换成二进制,再进行与运算
# “与运算”的规则是:同时为 1;则为 1
# 返回结果是十进制,将与运算后的二进制转化的十进制
# 此处的 0xffffffff中的 0x 表示16进制,1个f代表4个1。
# 整体解释为 2进制的 32个1;
n = n & 0xffffffff
print(n)
print(bin(n))
# 将2进制数转化为一个字符串,去除前两位"ob"
bin2 = str(bin(n))[2:]
print(bin2)
count = 0
for i in str(bin2):
if i == '1':
count += 1
return count
print(oneCount1(12))
print(oneCount1(-12))
执行结果如下所示:
0b1100
0b1100
1100
2
-0b1100
4294967284
0b11111111111111111111111111110100
11111111111111111111111111110100
29
解法2
思路分析
解法2的前半步和解法1相同,即先将一个整数转化成一个二进制数;
利用”按位与“的方法,取各个位上的数字,判断如果等于0,计数器+1,反之跳过;
代码实现
def oneCount2(n):
print(bin(n))
if n < 0:
n = n & 0xffffffff
print(n)
print(bin(n))
m = len(bin(n)) - 2
count = 0
for i in range(0, m):
"""
1101 = 13
&
0001 = 1 0001 count++
0010 = 2 0000
0100 = 4 0100 count++
1000 = 8 1000 conut++
"""
if n & 2 ** i != 0:
count += 1
return count
print(oneCount2(13))
print(oneCount2(-13))
执行结果如下:
0b1101
0b1101
3
-0b1101
4294967283
0b11111111111111111111111111110011
30