【问题标题】:compute x * y without arithmetical operators在没有算术运算符的情况下计算 x * y
【发布时间】:2019-12-26 16:02:13
【问题描述】:

我目前正在使用 python 进行“编程面试要素”,并且已经在这部分卡住了 3 天。下面的代码只是简单地将两个数字相乘而不使用任何运算符;作者给出的解释如下:

“小学教的十进制乘法算法确实 不要使用重复的加法——它使用 shift 和 add 来实现很多 更好的时间复杂度。我们可以对二进制数做同样的事情-to 将 x 和 y 相乘,我们将结果初始化为 0 并遍历 x 的位,如果 r 的第 k 位为 1,则将 2ky 添加到结果中。 值 (2^k)*y 可以通过将 y 左移 k 来计算。既然我们不能 直接使用add,我们必须实现它。我们申请小学 二进制情况的加法算法,即计算总和 一点一点,并“涟漪”随身携带。”

def multiply(x, y):
    def add(a, b):
        running_sum, carryin, k, temp_a, temp_b = 0, 0, 1, a, b

        while temp_a or temp_b:
            ak, bk = a & k, b & k
            carryout = (ak & bk) | (ak & carryin) | (bk & carryin)
            running_sum |= ak ^ bk ^ carryin
            carryin, k, temp_b, temp_b = (
                carryout << 1, k << 1, temp_a >> 1, temp_b >> 1)

        return running_sum | carryin

    running_sum = 0
    while x:  # Examines each bit of x
        if x & 1:
            running_sum = add(running_sum, y)
        x, y = x >> 1, y << 1

    return running_sum


print(multiply(2, 2))

我的问题是:

  1. 变量“ak”和“bk”的用途是什么
  2. 进位变量发生了什么;为什么我们对 (ab & bk, ak & carry and bk & carryin) 使用按位与运算符,然后使用按位或?
  3. 变量“running_sum”如何使用按位异或和按位或来跟踪总和?
    1. 我们为什么要返回“running_sum | carryin”

如果能帮助您理解此代码,我们将不胜感激。提前致谢。

【问题讨论】:

    标签: python python-3.x algorithm bit-manipulation bitwise-operators


    【解决方案1】:

    add 中,我们将两个二进制数逐位相加。

    • k 是我们正在查看的位。
    • akbkk-th 位 ab 的值
    • 如果先前的akbk 或先前的进位 (carryin) 中至少有两个为 1,则下一个数字的进位将为 1。因此,carryout = (ak &amp; bk) | (ak &amp; carryin) | (bk &amp; carryin)
    • k-th 数字中,如果akbkcarryin 的奇数为1,我们得到1。因此,ak ^ bk ^ carryin。由于我们只得到一位,我们可以通过应用 OR 将其添加到 running_sum
    • 最后,当ab 用尽时(我们达到了它们的最高有效位),我们仍然需要注意可能剩余的进位标志。因此,running_sum | carryin

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      • 2021-11-09
      相关资源
      最近更新 更多