利用位运算实现加、减、乘、除

1.加法

加法其实主要问题是怎么处理进位,当然我们可以每一位分别相加,然后用一个变量来保存下一位是否进位
private static int add(int a, int b) {
		int res = 0;
		int jinwei = 0;
		for(int i = 0 ; i <32 ; i++){
			int numA = (a>>i) & 1;
			int numB = (b>>i) & 1;
			if((numA & numB)>0){
				if(jinwei>0){
					res |= 1 << i;
				}
				jinwei = 1;
			}else if((numA | numB) > 0){
				if(jinwei == 0){
					res |= 1<< i;
				}
			}else{
				if(jinwei >0){
					res |= 1<<i;
					jinwei = 0;
				}
			}
		}
		return res;
	}

还有一种方法,思想是把进位和每个位之间的运算分开来求,然后再递归求和,直到不再产生进位为止。
private static int add2(int a, int b) {
		if( b == 0) return a;
		int sum = a^b;
		int jinwei = (a&b)<<1;
		return add2(sum,jinwei);
	}

减法无非就是加上一个数的相反数

2.乘法

a x b ,如果把 b 写成2进制表示,那么就是  ax(b0x2^0) + a x(b1x2^1) .....  其中bi表示b的2进制中第i位为1或者0,然后我们知道,一个数乘以2的k次方,就是左移k次。
private static int multi(int a, int b) {
		int ans = 0;
		for(int i = 0; i < 32; i++){
			if((b & 1) > 0){
				ans = add(ans,a);
			}
			a<<=1;
			b>>=1;
		}
		return ans;
	}

3.除法

除开符号(我们假设2个数都是正数),除法的话,最容易想到的就是,每次减一个除数,看要减多少次使得被除数小于除数,就可以算出结果,但是有一个更快速的方法,例如 11/ 5    ,  用二进制表示  1011 / 0101   可以写成   101<<1 + 1 ,起始就是说,有 2<<1 个101, 用上面那个方法我们可以一次性减去 2^k次方个除数。
private static int divide(int a, int b) {
		int res = 0;
		int num = 0;
		for(int i = 31;i>=0 ; --i){
			num<<=1;
			num |=(a >> i) & 1;
			if(num >= b){ //如果当前累计的数大于除数,那么就可以减去除数,此时减去了 2^i次方个除数。
				num -= b;
				res |= (1<<i);
			}
		}
		return res;
	}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值