位运算实现加减乘除运算(另类加减乘数)

当不可以使用加减乘数直接计算两个数字的结果的时候,那么我们可以使用位运算来计算这些结果,具体代码如下:

  1. 加法:

// 递归求解
int add(int num1, int num2){
	if (num2 == 0)
		return num1;

	int sum = num1 ^ num2;
	int carry = (num1 & num2) << 1;
	return add(sum, carry);
}

// 递推求解
int add2(int num1, int num2){
	int sum = num1 ^ num2;
	int carry = (num1 & num2) << 1;

	while (carry != 0){
		int a = sum;
		int b = carry;
		sum = a ^ b;
		carry = (a & b) << 1;
	}

	return sum;
}
  1. 减法

//取补码
//int negative(int num){
//
//	return add(~num, 1);
//}

//做减法
int sub(int num1, int num2){
	int negative = add(~num2, 1);
	return add(num1, negative);
}
  1. 乘法

//做乘法
//num1 被乘数;	num2 乘数
int multiply(int num1, int num2){
	// 取 num1 与 num2 的绝对值
	int multiplicand = num1 < 0 ? add(~num1, 1) : num1;
	int multiplier = num2 < 0 ? add(~num2, 1) : num2;

	int ret = 0;
	// 计算绝对值的乘机
	while (multiplier > 0){
		// 检查乘数最后一位是否为1
		if ((multiplier & 0x1) > 0)
			ret = add(ret, multiplicand);

		multiplicand <<= 1;	// 每次计算完都要将被乘数向左移一位
		multiplier >>= 1;	// 每次计算完都要将被乘数右移一位
	}
	// 计算俩个数字的符号,相同为正,相异为负
	if ((num1 ^ num2) < 0)
		ret = add(~ret, 1);

	return ret;
}
  1. 除法

//做除法
// dividend 被除数
// divisor 除数
int divide(int num1, int num2){
	// 计算被除数和除数的绝对值
	int dividend = num1 < 0 ? add(~num1, 1) : num1;
	int divisor = num2 < 0 ? add(~num2, 1) : num2;

	int quotient = 0;	// 商
	int remainder = 0;	// 余数

	while (dividend >= divisor){
		quotient = add(quotient, 1);
		dividend = sub(dividend, divisor);
	}
	// 计算符号,相同则商为正,不同则商为负
	if ((num1 ^ num2) < 0)
		quotient = add(~quotient, 1);
	// 计算余数的符号
	remainder = num2 > 0 ? dividend : add(~dividend, 1);

	return quotient;
}

int divide2(int num1, int num2){
	// 计算被除数和除数的绝对值
	int dividend = num1 < 0 ? add(~num1, 1) : num1;
	int divisor = num2 < 0 ? add(~num2, 1) : num2;

	int quotient = 0;	// 商
	int remainder = 0;	// 余数

	//比较dividend是否大于divisor的(1<<i)次方,不要将dividend与(divisor<<i)比较,而是用(dividend>>i)与divisor比较,
    //效果一样,但是可以避免因(divisor<<i)操作可能导致的溢出,如果溢出则会可能dividend本身小于divisor,但是溢出导致dividend大于divisor   
	for (int i = sizeof(int)* 8 - 1; i >= 0; i--){
		if ((dividend >> i) >= divisor){
			quotient = add(quotient, 1 << i);
			dividend = sub(dividend, divisor << i);
		}
			
	}
	// 计算符号,相同则商为正,不同则商为负
	if ((num1 ^ num2) < 0)
		quotient = add(~quotient, 1);
	// 计算余数的符号
	remainder = num2 > 0 ? dividend : add(~dividend, 1);

	return quotient;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值