位运算实现整数运算
不准用+,-,*,/ 运算操作符来实现四则运算。
1、整数加法
https://leetcode.com/problems/sum-of-two-integers/
int add(int a, int b) { int ans = a; while (b) {//直到没有进位 ans = a ^ b; //不进位加法 b = ((a & b) << 1); //所有a,b都为1的位,都存在进位,记录该进位,下一次循环加上 a = ans; } return ans; }
链接的题目需要处理下溢出的问题:
class Solution { public: int getSum(int a, int b) { int ans = a; while (b) { ans = a ^ b; b = ((unsigned)a & b) << 1;//(其实没什么意义,返回值又不是unsigned int,但不这样写,会Runtime Error) a = ans; } return ans; } };
2、整数减法
计算机内部的减法运算,就是通过加上被减数相反数的补码实现的。
即: a - b 和 a + (~b + 1) 是等价的。
int sub(int a, int b) { b = add(~b, 1);//取b的补码 return add(a, b); }
3、整数乘法
快速幂的思想,溢出风险比较大,改用long long了。
long long Multi(long long a, long long b){ long long ans = 0; while (b){ if (b & 1) ans = add(ans, a);//将add的两个形参也改为long long a <<= 1; b >>= 1; } return ans; }
4、整数除法
//依次减掉(如果x够减的)y^(2^31),y^(2^30),...y^8,y^4,y^2,y^1。减掉相应数量的y就在结果加上相应的数量。 int Div(int x, int y){ int ans = 0; for (int i = 31; i >= 0; i--){ //比较x是否大于y的(1<<i)次方,避免将x与(y<<i)比较,因为不确定y的(1<<i)次方是否溢出 if ((x >> i) >= y){ ans += (1 << i); x -= (y << i); } } return ans; }