【C++】位运算实现加减乘除
1 #include<iostream> 2 #include<assert.h> 3 using namespace std; 4 5 // 位运算实现加减乘除 6 7 int myAdd(int num1, int num2) 8 { 9 if (num2 == 0) return num1; 10 int sum = 0, carry = 0; 11 sum = num1 ^ num2; // 按位抑或 12 carry = (num1 & num2) << 1; 13 return myAdd(sum, carry); 14 } 15 16 int myAddIter(int num1, int num2) 17 { 18 int ret = 0; 19 while (num2) 20 { 21 ret = num1 ^ num2; 22 num2 = (num1 & num2) << 1; 23 num1 = ret; 24 } 25 return ret; 26 } 27 28 int myNeg(int num1) 29 { 30 // 正数到负数的补码表示: 取反加1 31 return myAdd(~num1, 1); 32 } 33 34 int myMinus(int num1, int num2) 35 { 36 return myAdd(num1, myNeg(num2)); 37 } 38 39 // (2^0)*k0 + (2^1)*k1 + (2 ^2)*k2 + ... + (2^31)*k31 40 int myPosMulti(int num1, int num2) 41 { 42 int ret = 0; 43 while (num2) 44 { 45 if (num2 & 1) // 对应当前num2的最低位是1 46 ret = myAdd(ret, num1); 47 num1 <<= 1; // num1 = num1 * 2 48 num2 >>= 1; // num2的当前位用过了就右移 49 } 50 return ret; 51 } 52 53 int myMultiply(int num1, int num2) 54 { 55 if (num1 >= 0 && num2 >= 0) 56 return myPosMulti(num1, num2); 57 if (num1 < 0 && num2 >= 0) 58 return myNeg(myPosMulti(myNeg(num1), num2)); 59 if (num1 >= 0 && num2 < 0) 60 return myNeg(myPosMulti(num1, myNeg(num2))); 61 if (num1 < 0 && num2 < 0) 62 return myPosMulti(myNeg(num1), myNeg(num2)); 63 } 64 65 // 除法就是由乘法的过程逆推,依次减掉(如果x够减的)y^(2^31),y^(2^30),...y^8,y^4,y^2,y^1。减掉相应数量的y就在结果加上相应的数量。 66 int myPosDiv(int num1, int num2) 67 { 68 num1 = num1 > 0 ? num1 : myNeg(num1); 69 num2 = num2 > 0 ? num2 : myNeg(num2); 70 if (num1 < num2) 71 return 0; 72 long long op = num2; 73 int ret = 0; 74 int flag; 75 int curBit = 0; 76 assert(num2 != 0); 77 while (op <= num1) 78 { 79 op <<= 1; 80 ++curBit; 81 } 82 op >>= 1; 83 --curBit; 84 85 while (op >= num2) 86 { 87 if (num1 >= op) 88 { 89 num1 -= op; 90 ret += 1 << curBit; 91 } 92 op >>= 1; 93 --curBit; 94 } 95 return ret; 96 } 97 98 int myPosDivByMinus(int num1, int num2) 99 { 100 int ret = 0; 101 while (num1 >= num2) 102 { 103 num1 = myMinus(num1, num2); 104 ret = myAdd(ret, 1); 105 } 106 return ret; 107 } 108 109 int myPosComp(int num1, int num2) 110 { 111 bool isZero(int); 112 int temp = 1; 113 num2 = num1 ^ num2; 114 if (isZero(num2)) return 0; 115 while (num2 >>= 1) 116 temp <<= 1; 117 return temp & num1; 118 } 119 120 121 int myDivide(int num1, int num2) 122 { 123 if ((num1 > 0 && num2 > 0) || (num1 < 0 && num2 < 0)) 124 return myPosDiv(num1, num2); 125 else 126 return myNeg(myPosDiv(num1,num2)); 127 } 128 129 bool isNeg(int num) 130 { 131 return num & 0x8000; 132 } 133 134 bool isZero(int num) 135 { 136 return !(num & 0xFFFF); 137 } 138 139 bool isPos(int num) 140 { 141 return !(num & 0x8000) && (num & 0xFFFF); 142 } 143 144 //int myMod(int a, int b) 145 //{ 146 // 147 //} 148 149 int divide(int dividend, int divisor) { 150 int ret = 0; 151 long long curDividend, curDivisor, op; 152 bool flag; 153 int curBit = 0; // 记录商的1在哪一位 154 if (divisor == 0) return INT_MAX; // 往负数方向溢出咋整 155 if ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)) 156 flag = 0; // 负数 157 else 158 flag = 1; 159 160 curDividend = abs(dividend); 161 curDivisor = abs(divisor); 162 163 if (curDividend < curDivisor) return 0; 164 165 op = curDivisor; 166 while (op <= curDividend) 167 { 168 ++curBit; 169 op = op << 1; 170 } 171 op = op >> 1; 172 --curBit; 173 174 while (op >= curDivisor) 175 { 176 if (curDividend >= op) 177 { 178 curDividend -= op; 179 ret += 1 << curBit; 180 } 181 op = op >> 1; 182 --curBit; 183 } 184 185 if (flag) 186 return ret; 187 return -ret; 188 } 189 190 int main() 191 { 192 //INT_MIN -2147483648 INT_MIN 2147483647 193 int a = INT_MAX; // 194 int b = -1; 195 cout << "myAdd: " << myAdd(a, b) << endl; 196 cout << "myMinus: " << myMinus(a, b) << endl; 197 cout << "myMultiply: " << myMultiply(a, b) << endl; 198 cout << "myDivide: " << myDivide(a, b) << endl; 199 // -1010369383, -2147483648 200 cout << "Leetcode: " << divide(-1010369383, INT_MIN) << endl; 201 //cout << "myMod: " << myMod(a, b) << endl; 202 system("pause"); 203 return 1; 204 }