题目链接地址:
题目描述:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入为两个整数m和n(1<=m,n<=1000000)。
输出:
对应每个测试案例,输出m+n的值。
样例输入:
3 4
7 9
样例输出:
7
16
解题思路:
不用加减乘除实现加法,那自然就想到神奇的位运算了。既然是位运算,那肯定就要把十进制数字转换成二进制了。
二进制数的加法满足以下规则:
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10
二进制数的异或运算满足以下规则:
0 ^ 0 = 0,0 ^ 1 = 1,1 ^ 0 = 1,1 ^ 1 = 0
二进制数的按位与运算满足以下规则:
0 & 0 = 0,0 & 1 = 0,1 & 0 = 0,1 & 1 = 1
因此可以用两个数的异或结果表示加法过程中所得到的临时和,用两个数按位与的结果再左移一位表示加法过程中的进位。
用位运算求a+b的过程如下:
(1)将a ^ b做为当前和结果jg,(a & b) << 1做为a+b的进位jw;
(2)如果jw为0,则jg就是a + b的结果,否则将jg赋值给a,jw赋值给b,跳转到步骤(1)继续执行。
举个栗子,a = 7,b = 9,求a + b的过程如下:
1)将7转换为二进制为0111,将9转换为二进制是1001,
则jg = a ^ b = 0111 ^ 1001 = 1110,
jw = (a & b) << 1 = (0111 & 1001) << 1 = 0010;
2)令a = jg = 1110,b = jw = 0010,
则jg = a ^ b = 1110 ^ 0010 = 1100,
jw = (a & b) << 1 = (1110 & 0010) << 1 = 0100;
3)令a = jg = 1100,b = jw = 0100,
则jg = a ^ b = 1100 ^ 0100= 1000,
jw = (a & b) << 1 = (1100 & 0100) << 1 = 1000;
4)令a = jg = 1000,b = jw = 1000,
则jg = a ^ b = 1000 ^ 1000= 0000,
jw = (a & b) << 1 = (1000 & 1000) << 1 = 10000;
5)令a = jg = 00000,b = jw = 10000,
则jg = a ^ b = 00000 ^ 10000 = 10000,
jw = (a & b) << 1 = (00000 & 10000) << 1 = 0,
因为jw = 0,所以此时可以得出a+b = 10000 = 16。
AC代码如下:
#include<stdio.h>
/**
* 0 ^ 0 = 0,0 ^ 1 = 1,1 ^ 0 = 1,1 ^ 1 = 0
* 0 & 0 = 0,0 & 1 = 0,1 & 0 = 0,1 & 1 = 1
* a + b 的结果由加法结果和加法进位组成
* (1)用 a ^ b 表示a + b的结果jg
* (2)用 (a & b) << 1 表示a + b的进位jw
* (3)再让结果jg与进位jw重复(1)(2)步骤,直至进位jw为0时,可以得到最后的求和运算结果jg
* @param a 用户输入的第一个整数
* @param b 用户输入的第二个整数
* @return jg 返回用户输入的两个整数之和
*/
int additionWithoutPlus(int a,int b)
{
int jg = a; // 存放"加法"的结果
int jw = b; // 存放"加法"的进位
int temp_a,temp_b; // temp_a存放临时的求和结果,temp_b存放临时的求和进位
while(jw)
{
temp_a = jg;
temp_b = jw;
jg = temp_a ^ temp_b; // 通过异或得到两个二进制数字的和
jw = (temp_a & temp_b) << 1; // 通过按位与再向左移动一位得到两个二进制数字相加得到的进位
}
return jg;
}
int main()
{
int sum;
int m,n;
while(EOF != scanf("%d%d",&m,&n))
{
sum = additionWithoutPlus(m,n);
printf("%d\n",sum);
}
return 0;
}
/**************************************************************
Problem: 1507
User: blueshell
Language: C
Result: Accepted
Time:10 ms
Memory:912 kb
****************************************************************/