while循环将执行多少次?

时间:2019-12-07 08:44:20

标签: python time-complexity bit-manipulation bitwise-operators addition

我想知道这个while循环会执行多少次。该功能使用XOR和AND将两个数字相加。

def Add(x, y): 

    # Iterate till there is no carry  
    while (y != 0): 

        # carry now contains common 
        # set bits of x and y 
        carry = x & y 

        # Sum of bits of x and y where at 
        # least one of the bits is not set 
        x = x ^ y 

        # Carry is shifted by one so that    
        # adding it to x gives the required sum 
        y = carry << 1

    return x 
``

2 个答案:

答案 0 :(得分:2)

对于while循环执行了多少次,没有固定的答案。当从一个位置到另一个位置有一个进位位时,总是执行while循环。因此,您需要知道数字在二进制中到底是什么样子。但是您可以肯定地说的是最大可能执行的次数。它是较大数字的长度,为位+1。为什么?因为如果那是最大数,则可以进行一次进位。让我们以add(1,7)= 8(001 + 111 = 1000)为例。从第一位开始的进位传递两个第二位置,然后传递到第三位置,然后传递到第四位置。 4次迭代等于7的长度和+ 1 =4。

答案 1 :(得分:2)

无进位加法器的算法:

function no_carry_adder(A,B)
    while B != 0:
        X = A XOR B, Bitwise-XOR of A,B.
        Y = A AND B, Bitwise-AND of A,B.
        A = X
        B = Y << 1, Multiplying Y by 2.
    return A

如您所见,while循环一次又一次地执行这四个指令,直到B = 0,并且当B = 0时,存储在A中的二进制数就是答案。 现在的问题是找出在whileB = 0变为零之前B循环将执行多少次。

如果我天真的做法,即按照任何编程语言中的描述编写算法,它都会给我一个答案,但是如果二进制字符串{{1}中的位数},而AB

如何制定更快的算法? 让我们看一下不同的情况,

  • 案例1:当两个> 500时。
           在这种情况下,循环将A = B = 0迭代为= 0的次数。
  • 情况2:B = 0A != 0时。
           在这种情况下,循环还将B = 0迭代为= 0的次数。
  • 情况3::当B = 0A = 0时。
           在这种情况下,循环迭代B != 0的次数,因为在第一次迭代之后,= 1的值就像您用X = B对任何二进制数进行bitwise XOR时一样结果就是数字本身。 0的值是因为Y = 0的任何数字的bitwise AND0。因此,您可以看到0然后是Y = 0B = 0
  • 情况4::当Y << 1 = 0A = BA != 0时。
           在这种情况下,循环迭代B != 0的次数是因为在第一次迭代中= 2的值是为什么,因为两个相同数字的A = 0总是bitwise XOR且值是0是因为两个相同数字的Y = B是数字本身,然后是bitwise AND,在第一次迭代后分别是B = Y << 1A = 0,因此这种情况变为情况3 。因此,迭代次数将始终为B != 0
  • 情况5::当2A != BA != 0时。
    在这种情况下,循环迭代B != 0的次数。

计算最长进位链长度的算法:

  • 首先将二进制字符串= length of the longest carry-chainA设置成相等的长度。

  • 我们知道最大进位序列的长度就是答案,我只需要找到到目前为止已经发生的最大进位序列长度即可。因此,要进行计算,

  • 我将从左向右迭代,即LSB到MSB,然后:

    • B表示该位标志着进位序列的开始,因此if carry + A[i] + B[i] == 2++curr_carry_sequence
    • carry = 1表示在这里消耗了通过前一个比特加法转发的进位,该位将产生一个新的进位,因此,进位序列的长度将重置为1,即if carry + A[i] + B[i] == 3和{{1 }}。
    • curr_carry_sequence = 1表示前一位生成的进位在此处解析,它将标记进位序列的结尾,因此进位序列的长度将重置为0。即carry = 1和{ {1}}。
  • 现在,如果if carry + A[i] + B[i] == 1 or 0的长度比curr_carry_sequence = 0的长度carry = 0,则更新curr_carry_seq

  • 答案为>

有关源代码,请参见No Carry Adder Solution

P.S。有关 No-Carry Adder 的平均案例分析,您可以参考以下文章:Average Case Analysis of No Carry Adder: Addition in log(n) + O(1)Steps on Average: A Simple Analysis