九度OJ-題目1507:不用加減乘除做加法
題目連結地址:
題目描述:
寫一個函式,求兩個整數之和,要求在函式體內不得使用+、-、*、/四則運算子號。
輸入:
輸入可能包含多個測試樣例。
對於每個測試案例,輸入為兩個整數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 ****************************************************************/