【问题标题】:How would I convert a number represented as an array of digits from base-2^k to binary?如何将表示为数字数组的数字从 base-2^k 转换为二进制?
【发布时间】:2015-12-12 05:07:33
【问题描述】:

我有一个算法可以模拟手动将二进制数转换为十进制数。我的意思是每个数字都表示为一个数字数组(从最低到最高有效),而不是使用语言的 int 或 bigint 类型。

例如,base-10 中的 42 将表示为 [2, 4],base-2 中的 10111 将表示为 [1, 1, 1, 0, 1]。

这里是 Python。

def double(decimal):
    result = []
    carry = 0
    for i in range(len(decimal)):
        result.append((2 * decimal[i] + carry) % 10)
        carry = floor((2 * decimal[i] + carry) / 10)
    if carry != 0:
        result.append(carry)
    return result

def to_decimal(binary):
    decimal = []
    for i in reversed(range(len(binary))):
        decimal = double(decimal)
        if binary[i]:
            if decimal == []:
                decimal = [1]
            else:
                decimal[0] += 1
    return decimal

这是我几个学期前的算法课作业的一部分,他在笔记中向我们提出了一个挑战,声称我们应该能够从这个算法中推导出一个可以将数字从base-2^k 到二进制。我今天挖了这个,它一直困扰着我(阅读:让我觉得很生疏),所以我希望有人能够解释我如何根据这个算法编写一个 to_binary(number, k) 函数。

【问题讨论】:

  • 这是一个比您已经解决的问题要简单得多的问题,因为底数都是 2 的幂。
  • base-2^k 中的每个数字变成二进制 k 位:5,13,31 in base-2^5 变成 00101,01101,11111,或者放在一起:@987654327 @.

标签: algorithm binary decimal


【解决方案1】:

基础2^k 有数字0, 1, ..., 2^k - 1

例如,在基数 2^4 = 16 中,我们将有数字 0, 1, 2, ..., 10, 11, 12, 13, 14, 15。为方便起见,我们使用字母表示较大的数字:0, 1, ..., A, B, C, D, E, F

假设您想将AB 转换为二进制。微不足道的事情是先将其转换为十进制,因为我们知道如何将十进制转换为二进制:

AB = B*16^0 + A*16^1 
   = 11*16^0 + 10*16^1
   = 171

如果你将171 转换为二进制,你会得到:

10101011

现在,有没有我们可以使用的捷径,这样我们就不用经过 base 10 了?有。

让我们在这部分停下来:

AB = B*16^0 + A*16^1 
   = 11*16^0 + 10*16^1

回想一下从十进制转换为二进制需要什么:整数除以 2,记下余数,最后以相反的顺序写余数:

number after integer division by 2 | remainder after integer division by 2
--------------------------------------------------------------------------
                                 5 | 1
                                 2 | 0
                                 1 | 1
                                 0 |

                  => 5 = reverse(101) = 101 in binary

让我们把它应用到这部分:

11*16^0 + 10*16^1 

首先,对于第一个4(因为16^1 = 2^4)除法,除以2 的余数将仅取决于11,因为16 % 2 == 0

11 | 1
5  | 1
2  | 0
1  | 1
0  |

所以我们二进制数的最后一部分将是:

1011

到我们完成此操作时,我们将摆脱16^1,因为到目前为止我们已经完成了4 部门。所以现在我们只依赖10

10 | 0
 5 | 1
 2 | 0
 1 | 1
 0 |

所以我们的最终结果将是:

10101011

这是我们用经典方法得到的!

我们可以注意到,我们只需要将数字单独转换为二进制,因为它们会单独和顺序地影响结果:

A = 10 = 1010
B = 11 = 1011

=> AB in binary = 10101011

对于您的基础2^k,执行相同操作:将每个单独的数字转换为二进制,从最高有效到最低,然后按顺序连接结果。

示例实现:

def to_binary(number, k):
    result = []
    for x in number:
        # convert x to binary
        binary_x = []
        t = x
        while t != 0:
            binary_x.append(t % 2)
            t //= 2
        result.extend(binary_x[::-1])

    return result

#10 and 11 are digits here, so this is like AB.
print(to_binary([10, 11], 2**4))
print(to_binary([101, 51, 89], 2**7))

打印:

[1, 0, 1, 0, 1, 0, 1, 1]
[1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1]

注意:上面的代码其实有一个bug。例如,基础2**7 中的2 将转换为二进制的10。但是基数2**7 中的数字应该有7 位,因此您需要将其填充到那么多位:0000010。我将把它留作练习。

【讨论】:

  • 美丽。谢谢 IVlad。
猜你喜欢
  • 2012-02-14
  • 2013-11-08
  • 1970-01-01
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 2019-05-14
相关资源
最近更新 更多