• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

【C++】位运算实现加减乘除

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
  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 }

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
springboot整合mybatis深坑之c3p0的详细配置发布时间:2022-07-13
下一篇:
C#Winform画线发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap