1. 程式人生 > 其它 >位運算:與、異或、移位

位運算:與、異或、移位

技術標籤:C++的日常位運算

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,引入無進位和進位的概率

a_{i}b_{i}無進位和進位
0000
0110
1010
1101

可以看出無進位和等於二者的異或運算結果,進位等於二者的與運算結果,考慮到進位是在高位,可以將其左移一位

這樣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;