剑指Offer

剑指Offer - 九度1507 - 不用加减乘除做加法
2013-11-29 20:00
题目描述:

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入为两个整数m和n(1<=m,n<=1000000)。

输出:

对应每个测试案例,输出m+n的值。

样例输入:
3 4
7 9
样例输出:
7
16
题意分析:
  求两个数的和而不能用加减乘除,很明显又得借助位运算了。回想一下学Verilog时加法器的实现,能记住下面这两个关系:
  sum = bit1 ^ bit2 ^ carry
  carry' = (carry & bit1) | (bit1 & bit2) | (bit2 & carry)
  其中sum是当前位的和,bit1和bit2是两数的当前二进制位,carry是上一位的进位,carry'是这一位的进位。
  简单解释一下俩式子:
    式子1:加法和异或的区别就在于加法可以进位,而异或不进位。
    式子2:三个数只要有两个以上的‘1’就有进位了,所以是三个
  接下来就是逐位相加,将进位carry一直向上传递了。要注意别让最高位的carry丢失掉,除非是超出了本身数据能表示的范围。
  既然是写个加法器,依然本着写Verilog的原则,拒绝for循环。以下是ac的代码。
 1 // 653474    zhuli19901106    1507    Accepted    点击此处查看所有case的执行结果    1020KB    1439B    10MS
 2 // 201311190151
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 void cal_onebit(const int m, const int n, int i, int &carry, int &res)
 7 {
 8     res = (res | 
 9         (
10             (m & (1 << i)) ^ 
11             (n & (1 << i)) ^ 
12             (carry << i)
13         )
14     );
15     carry = 
16         (
17             (m & (1 << i)) & 
18             (n & (1 << i))
19         ) || 
20         (
21             (n & (1 << i)) & 
22             (carry << i)
23         ) || 
24         (
25             (carry << i) & 
26             (m & (1 << i))
27         );
28 }
29 
30 int main()
31 {
32     int m, n;
33     int res;
34     int carry;
35     
36     while(scanf("%d%d", &m, &n) == 2){
37         carry = 0;
38         res = 0;
39         cal_onebit(m, n, 0, carry, res);
40         cal_onebit(m, n, 1, carry, res);
41         cal_onebit(m, n, 2, carry, res);
42         cal_onebit(m, n, 3, carry, res);
43         cal_onebit(m, n, 4, carry, res);
44         cal_onebit(m, n, 5, carry, res);
45         cal_onebit(m, n, 6, carry, res);
46         cal_onebit(m, n, 7, carry, res);
47         cal_onebit(m, n, 8, carry, res);
48         cal_onebit(m, n, 9, carry, res);
49         cal_onebit(m, n, 10, carry, res);
50         cal_onebit(m, n, 11, carry, res);
51         cal_onebit(m, n, 12, carry, res);
52         cal_onebit(m, n, 13, carry, res);
53         cal_onebit(m, n, 14, carry, res);
54         cal_onebit(m, n, 15, carry, res);
55         cal_onebit(m, n, 16, carry, res);
56         cal_onebit(m, n, 17, carry, res);
57         cal_onebit(m, n, 18, carry, res);
58         cal_onebit(m, n, 19, carry, res);
59         cal_onebit(m, n, 20, carry, res);
60         printf("%d
", res);
61     }
62     
63     return 0;
64 }
原文地址:https://www.cnblogs.com/zhuli19901106/p/3450260.html