不用加减乘除实现两个正整数的加法

很常见的一道题,网上也有各种各样的解法,备忘一下。

首先来看十进制整数的加法,123 + 999,将其分为三步来运算:

(1)对每一位相加,不考虑进位。当有进位时,舍弃。如下:

     123

+   999

=   012  

(2)考虑进位的影响。观察可发现,当个位相加有进位时,实际上少加了10,当百位有进位时,实际上少加了100,依次类推。因此,第二步操作我们得到因为没考虑进位少加的数。当没有进位时为0,当有进位时,舍弃个位,留下十位。比如5 + 6 = 11,舍弃个位,留下十位,为1,即 5 + 6 = 1。对每一位做如此操作:

     123

+   999

=   111

个位: 3 + 9 = 1  少加了10

十位: 2 + 9 = 1  少加了100

百位: 1 + 9 = 1  少加了1000

共少加了 1100,即 111 * 10 = 1110。因为是十进制,所以将进位相加得到的数 111 * 10,即为由于忽略进位少加的数

(3)将第一步和第二步所得到的数相加:

     012

+ 1100

= 1112

得到最后的结果。

推广到二进制,逢2进1。举例:15 + 11,转化成二进制就是:1111 + 1011,还是按照上面的三个步骤:

(1)每一位相加,不考虑进位:

     1111

+   1011

=   0100

(2)考虑进位,算出少加的数

       1111

+     1011

=     1011

对应到二进制,从右到左:

第一位进位:少加了2

第二位进位:少加了4

第四位进位:少加了16

因为是二进制,需要将 1011 * 2,对应到二进制中,就是左移一位,变成 10110

(3)将第一步和第二步的数相加:

0100 = 4

10110 = 22

和为: 26

使用二进制加法时:

        0100

+    10110

=    11010

实际上,在上述过程中仍然有进位,继续利用上面的方法。因此,利用二进制实现加法实际上是个循环的过程。

用程序实现上述步骤:

第一步中,1 + 1 = 0, 0 + 0 = 0, 1 + 0 = 1, 0 + 1 = 1 ,实际上符合异或的操作(相同为0,不同为1)

第二步中,1 + 1 = 1, 0 + 0 = 0, 1 + 0 = 0, 0 + 1 = 0, 实际上符合与操作(只有都为1时才为1)

第三步就是对第一步和第二步的重复。

代码如下:

while(cin >> n >> m){
    while(m){
        int sum = n ^ m;
        int temp = (n & m)<<1;
        n = sum;
        m = temp;
    }
    cout << n << endl;    
}
View Code
原文地址:https://www.cnblogs.com/acBool/p/4878927.html