位運算:與、異或、移位
阿新 • • 發佈:2020-12-29
1. 原題分析
刷leetcode的時候,一直會遇到不用加法乘法去實現2個數的加法乘法運算,這類題目基本上就是利用位運算沒跑了,現在總結一下,
題目:劍指offer65. 不用加減乘除法做加法
https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/
分析:
設a=7,b=5;即a=111,b=101,引入無進位和進位的概率
無進位和 | 進位 | ||
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
可以看出無進位和等於二者的異或運算結果,進位等於二者的與運算結果,考慮到進位是在高位,可以將其左移一位
這樣a+b = a^b + (a&b)<<1 【這樣看可能不太明顯,大家可以用筆寫一遍,用二進位制計算2個數的加法】
因為上式中還包含了“+”,我們可以將其轉換成迴圈或者遞迴的方式,終止狀態是進位為0,即a&b<<1==0
#include<iostream> #include<cmath> #include<vector> #include <algorithm> #include <map> #include <algorithm> #include <unordered_map> using namespace std; class Solution { public: int add(int a, int b) { while (b != 0) { int c = unsigned(a & b) << 1; //需要轉換成無符號數,否則對大的負數會溢位,加上括號是<<運算優先順序比&高 a = a ^ b; b = c; } return a; } }; int main() { Solution obj; cout<<obj.add(111, 899); return 0; }
2. 引申
2.1 引申至10進位制
設a=103,b=97,則進位是010,無進位和190,區別於二進位制,這裡需要對進位乘10,即:
a+b = 190 + 1*(10^1),所以對於任意2個數,二者和都可以看做進位+無進位和。
2.2 引申至減法
設a=13,b=7,a=0x1101,b=0x0111,則無借位差是1010,借位是0100,區別於加法,這裡需要對借位進行減法,即:
a+b = 0x1010 - 0x0100 = 10 - 4 = 6;