力扣1 A B 問題(位運算 加減乘除)

2021-10-23 04:22:42 字數 3169 閱讀 7948

給出兩個整數 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為進製...