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


  “在小学时教的用于十进制乘法的算法确实
  不使用重复加法-它使用shift和加法来实现很多
  时间复杂度更高。我们可以对二进制数字执行相同的操作
  将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))


我的问题是:


变量“ ak”和“ bk”的目的是什么
结转vvariable发生了什么;为什么我们对(ab&bk,ak&carrying和bk&carryin)使用逐位和运算符,然后使用逐位或运算符?
变量“ running_sum”如何使用按位XOR和按位OR跟踪总和?


为什么我们返回“ running_sum |随身携带”



在理解此代码的任何帮助将不胜感激。提前致谢。

最佳答案

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


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

09-25 20:36