使用位操作的加法

441 阅读4分钟

Addition using Bitwise Operations

在这篇文章中,我们解释了如何使用位运算符,如and,xor, 和left shift 运算符,而不是使用普通的加法运算符 (+),来实现任意两个正数的相加

主题表

  1. 位操作的基础知识
  2. 使用位操作符进行两个数的相加
  3. 使用递归进行位加
  4. 位加法的时间和空间复杂度

比特运算的基础知识

我们知道,计算机以二进制数字0s和1s的形式存储各种数据(视频、文件、照片等)。这些0s和1s被称为比特,可以对这些二进制数字进行的各种运算被称为顺位运算。

下面给出了各种位运算符
Addition using Bitwise Operations
让我们举个例子,看看这些运算是如何工作的。

考虑两个十进制数字ab

a = 25 ,25的二进制等价物是 00011001

b = 14 ,14的二进制等价物是 00001110

1.位- 位数和只有在两个位都是1的情况下才会返回1。
Addition using Bitwise Operations
2.2.顺时针或- 顺时针或在任何一个位是1的情况下返回1。
Addition using Bitwise Operations
3.比运算 - 比特不运算返回位的补码。
Addition using Bitwise Operations
4.Bitwise Xor- Bitwise xor只有在其中一个位为零时才会返回1。
Addition using Bitwise Operations
5.位数左移
Addition using Bitwise Operations
在上图中,我们可以看到三个0,在右边,也就是在最小有效位之后,导致向左移动。

6.位向右移
Addition using Bitwise Operations
在上图中,我们可以看到三个0,在左边,即最有意义的位之后,导致向右移位。

现在我们已经了解了分位运算符的工作原理,让我们继续进行没有加法运算符的两数相加。

使用逐位运算符的两个数字相加

让我们先看看二进制层面的加法是如何发生的,并在尝试用位操作符做加法之前理解它。
Addition using Bitwise Operations
二进制加法与通常的加法很相似。从上面的例子中,我们可以了解到

  • 1 + 0 = 0 + 1 = 1
  • 0 + 0 = 1
  • 1 + 1 = 10 ,即2的二进制等价物。

另一个需要注意的要点是,当我们得到101 被带到进位,0 被保留在底部。

真值表会让我们更好地理解二进制加法是如何发生的。
Addition using Bitwise Operations
从真值表中,我们可以推断出

  • 进位表达式是A & B
  • 和表达式为A ^ B

利用以上两个表达式,任何两个数字的加法都可以按以下步骤完成。

步骤

  1. 得到两个正数ab 作为输入
  2. 然后检查数字b 是否不等于0
    • 找到carry 的值 (a & b)
    • 找到sum 的值(a ^ b),并将其存入变量中。a
    • 然后将进位向左移动1位,将其存入变量中。b
  3. 再次回到步骤2
  4. 当b变成0时,最后返回总和
def Bitwise_add(a,b):
    while b != 0:
        carry = a&b # Carry value is calculated 
        a = a^b # Sum value is calculated and stored in a
        b = carry<<1 # The carry value is shifted towards left by a bit

    return a # returns the final sum

这段代码背后的整个想法是,进位与和值再次相加。所以我们要做的是,用表达式a & b ,分别找到进位的值,然后再用它来找和。我们一直这样做,直到进位值变成0。

这里需要注意的另一点是,我们将进位向左移了1位。这是因为进位值被添加到下一个位,而不是当前位。看一下这张图片,以获得更好的理解。
Addition using Bitwise Operations
我们继续重复这个过程,直到结转值,即a & b ,变成0 。最后,我们得到所需的两个数字的总和。

使用递归进行位加

使用位运算符的加法也可以用递归的方式进行。同样的逻辑发生,但我们使用一个递归函数来做加法,而不是一个循环。

def Bitwise_add(a,b):
    if b == 0:
        return a
    else :
        return Bitwise_add(a^b , (a&b) << 1)

在这段代码中,a^b 是_和的表达式_,(a&b) << 1 是移位后的_携带表达式_。所以它被直接作为输入传递给递归函数。当进位表达式变成0 ,即b 变成0 ,递归循环停止。

位加法的时间和空间复杂度

该算法的时间复杂度为O(N),其中N是数字中的比特数。该算法的空间复杂度为O(1)。

给定一个数字M,比特数N等于logM。所以,两个数字M的相加不是一个恒定时间的O(1)操作。它需要log(M)时间。对数的基数是2。

总结

位操作是任何编程语言的一个组成部分,对它们有一个很好的理解将帮助你成为一个更好的程序员。通过OpenGenus的这篇文章,你一定对使用位操作的加法有了深刻的认识。