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

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<

还有一种方法,思想是把进位和每个位之间的运算分开来求,然后再递归求和,直到不再产生进位为止。
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<

 

你可能感兴趣的:(算法)