位操作实现加减乘除四则运算

http://blog.csdn.net/itismelzp/article/details/49621741

位操作实现加减乘除四则运算



1 先来掌握一些常用的位运算操作:

(1)等式:-n = ~(n - 1) = ~n + 1(-n等于其各位取反加1);

(2)获取整数n的二进制中最后一个1:-n&n 或(~n+1)&n或 ~(n - 1)&n;

如:n = 010100,则 -n = 101100, n&(n - 1)=000100;

(3)去掉整数n的二进制中最后一个1:n&(n - 1)。如:n = 010100, n -1 = 010011, n&(n - 1) = 010000。


2 四则运算实现

(1)加法(a + b)

用^、&和<<即可实现,a^b可得到对应位没有进位时的和,a&b可得到各位产生的进位值。

如:a=010010, b=100111,计算过程如下:

第一轮:a^b=110101,(a&b)<<1=000100(进位)。由于进位大于0,进入下一轮:a=110101,b=000100;

第二轮:a^b=110001,(a&b)<<1=001000(进位)。进位大于0,进入下一轮:a=110001,b=001000;

第二轮:a^b=111001,(a&b)<<1=000000(进位)。进位等于0,终止;

结果为:111001。


非递归代码如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int add(int a, int b)  
  2. {  
  3.     int carry; // 进位  
  4.     while (b)  
  5.     {  
  6.         carry = (a & b) << 1; // a & b取各位的进位,进位作用于对应位的高1位  
  7.         a = a ^ b;  
  8.         b = carry;  
  9.     }  
  10.     return a;  
  11. }  

递归代码如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int add_recursion(int a, int b)  
  2. {  
  3.     if (0 == b) return a;  
  4.     else  
  5.     {  
  6.         int carry = (a & b) << 1;  
  7.         a = a ^ b;  
  8.         return add_recursion(a, carry);  
  9.     }  
  10. }  


(2)减法(a - b)

减法可以转化成加法:a - b = a + (-b) = a + (~b + 1)

因此代码如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int sub(int a, int b)  
  2. {  
  3.     return add(a, add(~b, 1));  
  4. }  


(3)乘法(a * b)

先看一个乘法算法:1011 * 1010

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1.    1011  
  2. *  1010  
  3. --------  
  4.   10110 (1011<<1,相当于乘以0010)  
  5. 1011000 (1011<<3,相当于乘以1000)  
  6. --------  
  7. 1101110  

因此乘法可以通过系列的移位和加法实现。

代码如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int mul(int a, int b)  
  2. {  
  3.     int ans = 0;  
  4.     while (b)  
  5.     {  
  6.         if (b & 1) ans = add(ans, a);  
  7.         a <<= 1;  
  8.         b >>= 1;  
  9.     }  
  10.     return ans;  
  11. }  


(4)除法(a / b)

除法就是由乘法的过程逆推,依次减掉(如果a够减的)b ^ (2 ^ 31), b ^ (2 ^ 30), ...b ^ 8, b ^ 4, b ^ 2, b ^ 1。减掉相应数量的b就在结果加上相应的数量。

1011 / 1010的部分步骤:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1.  10110000 / 1010  
  2.  10110100  
  3. -10100000 (1010<<4)  
  4. ----------  
  5.     10100  
  6. -   10100 (1010<<1)  
  7. ----------  
  8.         0  

代码如下:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int div(int a, int b)  
  2. {  
  3.     int ans = 0;  
  4.     for (int i = 31; i >= 0; i--)  
  5.     {  
  6.         //比较a是否大于b的(1<<i)次方,避免将a与(b<<i)比较,因为不确定b的(1<<i)次方是否溢出   
  7.         if (b <= (a >> i))  
  8.         {  
  9.             ans += (1 << i);  
  10.             a -= (b << i);  
  11.         }  
  12.     }  
  13.     return ans;  
  14. }  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值