凑数法实现十进制转二进制

1. 除2取余法实现十进制转二进制

众所周知,十进制转二进制最广为人知、家喻户晓的方法,就是

整数部分除2取余,小数部分乘2取整

这个方法简单便捷易上手,且代码实现也比较简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sys

num = input("传统方法十进制转二进制整数部分\n请输入十进制整数:")

while True:
if num.isdigit():
num = int(num)
if num <= sys.maxsize:
break
num = input("非法输入,请重试:")

result = ''
temp = num

while temp>0:
result = str(temp % 2) + result
temp = int(temp / 2)
print(result,temp)

print(num,"的二进制结果为:",result)

2. 凑数法实现十进制转二进制

2.1 凑数法是什么

简单来说,凑数法是将每一位1乘上该位对应的2^(n-1)再累加起来,所以会出现每一项都等于此项前所有项的和的性质。

举个栗子:

123 = 64 + 32 + 16 + 8 + 2 + 1 = 26 + 25 + 24 + 23 + 21 + 20 = 1111011

可以看到,123是将除了4=22以外,即除了第3位以外的第1、2、4、5、6、7位上的2(n-1)相加,即为所求。而将这些位填上1,其余位填上0即为1111011。

2.2 凑数法另一种解读

上面的这种方式如果用手算的话计算量太大,还不如直接用除2取余来的划算。所以有了第二种解读。

另一种解读方式为比较法

还是上面这个例子,我们先列出一张2的n次幂的表,接着从高位开始用123与之比较,若123小则取0;若123大取1,且减去2的n次幂。然后移动至低一位用新的数接着比较。如下图所示,以此类推,当比较完所有位后,即可得出结果。

2.3 python代码实现凑数法

代码实现有很多种方式,这里选取的是第二种解读方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import sys

num = input("十进制转二进制凑数法整数部分实现\n请输入十进制整数:")

# 2^63=9223372036854775808
# sys.maxsize=2^63
# 防止数值越界
while True:
if num.isdigit():
num = int(num)
if num <= sys.maxsize:
break
num = input("非法输入,请重试:")

max_index = 1
for i in range(0,63):
if num < pow(2,i):
max_index = i-1
#print(max_index)
break

result = ''
temp = num
for index in range(max_index,-1,-1):
if temp >= pow(2,index):
result = result + '1'
temp = abs(temp - pow(2, index))
else:
result = result + '0'

print(num,"的二进制结果为:",result)

3. 凑数法优势?

那么看到这里有朋友可能要说,那是不是凑数法一定比取2取余法好用呢?

要想知道结果很简单,在代码里加入time模块来监视程序运行时间,比较之下就能知道孰胜孰劣。修改代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import sys
import time

# 输入
def input_num():
num = input("十进制转二进制凑数法整数部分实现\n请输入十进制整数:")
while True:
if num.isdigit():
num = int(num)
if num <= sys.maxsize:
break
num = input("非法输入,请重试:")
return num

# 凑数法
def comparison_method(num):
max_index = 1
for i in range(0,63):
if num < pow(2,i):
max_index = i-1
break
result = ''
temp = num
for index in range(max_index,-1,-1):
if temp >= pow(2,index):
result = result + '1'
temp = abs(temp - pow(2, index))
else:
result = result + '0'
return result


# 除2取余
def division_method(num):
result = ''
temp = num
while temp>0:
result = str(temp % 2) + result
temp = int(temp / 2)
return result


if __name__ == '__main__':
num = input_num()
start = time.perf_counter()
result1 = comparison_method(num)
middle = time.perf_counter()
result2 = division_method(num)
end = time.perf_counter()
print(num,"凑数法结果为:",result1,"用时:",str(middle-start))
print(num,"除2取余法结果为:",result2,"用时:",str(end-middle))

输入123456,输出结果如下图所示。

可见凑数法并没有比除2取余法快,反而更慢了,而且这种差距随着数字增加继续扩大

因为在位数多的情况下,凑数法不仅要跟所有位进行比较,还要作减法;而除2取余只有除法,这一点在计算机速度上可以体现出来。

而且在实际手算中,除2取余法也要比凑数法更快(数字不小的情况下)。这也难怪除2取余法会成为最为流行的十进制转二进制方法了。


凑数法实现十进制转二进制
https://huihui486.github.io/2023/01/18/Python/凑数法实现十进制转二进制/
作者
灰灰
发布于
2023年1月18日
许可协议