給出兩個整數 aa 和 bb , 求他們的和。
顯然你可以直接 return a + b,但是你是否可以挑戰一下不這樣做?(不使用++等算數運算子)
#include "stdafx.h"
class solution
return sum;
}};int main()
補充知識:
位運算(按位與、按位或、異或)
按位與運算子(&)
參加運算的兩個數,按二進位制位進行「與」運算。
運算規則:只有兩個數的二進位制同時為1,結果才為1,否則為0。(負數按補碼形式參加按位與運算)
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
例:3 &5 即 00000011 & 00000101 = 00000001 ,所以 3 & 5的值為1。
按位或運算子(|)
參加運算的兩個數,按二進位制位進行「或」運算。
運算規則:參加運算的兩個數只要兩個數中的乙個為1,結果就為1。
即 0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1 。
例:2 | 4 即 00000010 | 00000100 = 00000110 ,所以2 | 4的值為 6 。
異或運算子(^)
參加運算的兩個數,按二進位制位進行「異或」運算。
運算規則:參加運算的兩個數,如果兩個相應位為「異」(值不同),則該位結果為1,否則為0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。
例: 2 ^ 4 即 00000010 ^ 00000100 =00000110 ,所以 2 ^ 4 的值為6 。
位運算實現加、減、乘、除運算
1. 加法運算
思路:第一步先不考慮進製,異或相加,對應位相加;第二步只考慮進製,與運算左移一實現進製;第三步判斷是否有進製,即判斷左移後的值是否為零則結束,不為零則迴圈。
運算過程:13 + 9 = 22
1、不考慮進製,分別對各位數進行相加,結果為sum:
個位數3加上9為2;十位數1加上0為1; 最終結果為12;
位運算異或實現
2、只考慮進製,結果為carry:
3 + 9 有進製,進製的值為10;
位運算與實現,左移一實現進製
3、如果步驟2所得進製結果carry不為0,對步驟1所得sum,步驟2所得carry重複步驟1、 2、3;如果carry為0則結束,最終結果為步驟1所得sum:
這裡即是對sum = 12 和carry = 10重複以上三個步驟,(a) 不考慮進製,分別對各位數進行相加:sum = 22; (b) 只考慮進製: 上一步沒有進製,所以carry = 0; (c) 步驟2carry = 0,結束,結果為sum = 22
// 遞迴寫法
int add(int num1, int num2)
// 迭**法
int add(int num1, int num2)
return sum;
}2. 減法運算
思路:第一步,將被減數變成補碼形式,取反加一;第二步,減數和被減數取反加一後相加
減法即乙個正數加上乙個負數
在計算機中,通過補碼儲存負數。補碼就是反碼加一
/** num1: 減數
* num2: 被減數
*/int substract(int num1, int num2)
3. 乘法運算
思路:先處理乘數和被乘數的絕對值的乘積,然後根據它們的符號確定最終結果的符號即可。
求絕對值:a<0?(~a+1):a;
被乘數在前,乘數在後 4 x 2,被乘數是4,乘數是2
其中:乘數和被乘數的絕對值的乘積也可以通過位運算求解
(1) 判斷乘數是否為0,為0跳轉至步驟(4)
(2) 將乘數與1作與運算,確定末尾位為1還是為0,如果為1,則相加數為當前被乘數;如果為0,則相加數為0;將相加數加到最終結果中;
(3) 被乘數左移一位,乘數右移一位;回到步驟(1)
(4) 確定符號位,輸出結果;
int multiply(int a, int b)
multiplicand = multiplicand << 1;// 每運算一次,被乘數要左移一位
multiplier = multiplier >> 1;// 每運算一次,乘數要右移一位(可對照上圖理解)
}
//計算乘積的符號
if((a ^ b) < 0)
return product;
}
#include "stdafx.h"
class solution
nq = nq << 1;//被乘數左移
nh = nh >> 1;//乘數右移
} return sum;
}};int main()
4. 除法運算
除法運算很容易想到可以轉換成減法運算,即不停的用除數去減被除數,直到被除數小於除數時,此時所減的次數就是我們需要的商,而此時的被除數就是餘數。這裡需要注意的是符號的確定,商的符號和乘法運算中乘積的符號確定一樣,即取決於除數和被除數,同號為證,異號為負;餘數的符號和被除數一樣。
除數的231,230,...,22,21,2^0倍嘗試去減被除數,如果減得動,則把相應的倍數加到商中;如果減不動,則依次嘗試更小的倍數。這樣就可以快速逼近最終的結果。
2的i次方其實就相當於左移i位,為什麼從31位開始呢?因為int型資料最大值就是2^31啊。
int divide_v2(int a,int b)
}
// 確定商的符號
if((a ^ b) < 0)
// 確定餘數符號
remainder = b > 0 ? dividend : add(~dividend, 1);
return quotient;// 返回商
}
#include "stdafx.h"
class solution
} return beishu;
}};int main()
位運算加減乘除
按位異或 按位與 按位或 計算機系統中,數值一律用補碼來表示 因為補碼可以使符號位和數值位統一處理,同時可以使減法按照加法來處理。對補碼做簡單介紹 數值編碼分為原碼,反碼,補碼,符號位均為0正1負。原碼 補碼 數值位取反加1 補碼 原碼 對該補碼的數值位繼續 取反加1 補碼 的絕對值 稱為真值 正數...
位運算實現加減乘除
include include 加法運算 int add int a,int b 補碼中正數轉負數的原理 int negative int a 減法運算 int sub int a,int b 判斷正負 bool isnegative int a 僅計算正數乘法 int multi help int...
位運算實現加減乘除
關於邏輯右移和算術右移 vs中,對於unsigned型別,是邏輯右移,對於signed,算術右移 加法器的實現 對於不考慮進製的加法 0 0 0 1 0 1 0 1 1 1 1 0 即是異或運算 考慮進製 0 0 1 0 0 0 1 0 1 1 1 即是與運算 以下程式,a即不考慮進製部分,b為進製...