使用位运算实现加减乘除

在不使用+,-,*,/,四则运算符号的情况下,通过基本位运算实现加减乘除四则运算。

1. C++中使用位运算实现加法

首先,我们通过对x和y进行&位运算,得出每一位上的进位。然后对x和y进行^位运算,得出没有加进位的和。最后将所得的和当做新的x,所得的进位往左移一位(第零位的进位输入为0)当做新的y,继续做上面的步骤,直到进位为0,此时x中保存的就是我们要求的x和y的和了。
实现代码如下:

int add(int a, int b)
{
  int sum = a;
  int carry = b;

  while(carry)
  {
    int tmps = sum;

    sum = tmps ^ carry;
    carry = (tmps & carry) << 1;
  }

  return sum;
}
2. C++中使用位运算实现减法

要想得到一个数的相反数,只要对这个数求2-补码就可以了,即取反加1操作。然后继续对得到的结果进行该操作就可以得到原来的数字。通过使用2-补码形式的编码,我们可以把减法运算顺利的转换成加法。只要对减数求2-补码,然后跟被减数相加即可得到差值。
通过上面的研究,要在代码中实现减法已经很明了,很简单了。第一步对减数取反然后加1,第二步将第一步所得值和被减数相加。具体代码如下:

int subtract(int a, int b)
{
  int subtrahend = add(~b, 1);

  int sub = add(a, subtrahend);

  return sub;
}
3. C++中使用位运算实现乘法

乘法最简单的理解就是,将被乘数加乘数次即可得到乘积。考虑到负整数的乘法,我们这里先对乘数和被乘数求绝对值,然后对绝对值进行上述的乘法操作。确定乘积符号的规则为同号为正,异号为负。这中实现方式比较简单,代码如下:

int multiply(int a, int b)
{
  //将乘数和被乘数都取绝对值
  int multiplier = a < 0 ?  add(~a , 1) : a;
  int multiplicand = b < 0 ? add(~b, 1) : b;

  //计算绝对值的乘积
  int product = 0;
  int count = 0;

  while(count < multiplier)
  {
    product = add(product, multiplicand);
    count = add(count, 1);
  }

  //计算乘积的符号
  if((a ^ b) < 0)
  {
    product = add(~product, 1);
  }

  return product;
}

上面的第一种实现方式虽然简单,但是效率太低。如果乘数和被乘数小一点还可以,如果大了那效率是不能忍受的。这里要实现的这种乘法,最多做log(n)次的加法操作,就可以求出乘积。这种方式和第一方式的相同点是,这里也是先对两数的绝对值就乘积,最后确定符号。这种实现方式就是对手动计算乘数的模拟。具体步骤如下:
1)根据乘数每一位为1还是为0,决定相加数取被乘数移位后的值还是取0;
2)各相加数从乘数的最低位开始求值,并逐次将相加数(被乘数)左移一位,最后一步求和
3)符号位根据同号为正异号为负的原则

int multiply(int a, int b)
{
  //将乘数和被乘数都取绝对值
  int multiplier = a < 0 ?  add(~a , 1) : a;
  int multiplicand = b < 0 ? add(~b, 1) : b;

  //计算绝对值的乘积
  int product = 0;
  while(multiplier)
  {
    if(multiplier & 0x1)
    {
      product = add(product, multiplicand);
    }

    multiplicand = multiplicand << 1;
    multiplier = multiplier >> 1;
  }

  //计算乘积的符号
  if((a ^ b) < 0)
  {
    product = add(~product, 1);
  }

  return product;
}
4. C++中使用位运算实现除法

最简单的除法实现就是不停的用除数去减被除数,直到被除数小于除数时,此时所减的次数就是我们需要的商,而此时的被除数就是余数。唯一需要注意的就是商的符号和余数的符号。商的符号确定方式也乘法是一样,即同号为正,异号为负。而余数的符号和被除数的符号是一样的。和简单的乘法实现一样,这里我们要先对两数的绝对值求商,求余数。最后再确定符号。具体实现代码如下:

//求商
int divide(int a, int b)
{
  //对被除数和除数取绝对值
  int dividend = a < 0 ? add(~a, 1) : a;
  int divisor = b < 0 ? add(~b, 1) : b;

  //对被除数和除数的绝对值求商
  int remainder = dividend;
  int quotient = 0;

  while(remainder >= divisor)
  {
    remainder = subtract(remainder, divisor);
    quotient = add(quotient, 1);
  }

  //求商的符号
  if((a ^ b) < 0)
  {
    quotient = add(~quotient, 1);
  }

  return quotient;
}

//求余
int remainder(int a, int b)
{
  //对被除数和除数取绝对值
  int dividend = a < 0 ? add(~a, 1) : a;
  int divisor = b < 0 ? add(~b, 1) : b;

  //对被除数和除数的绝对值求商
  int remainder = dividend;
  int quotient = 0;

  while(remainder >= divisor)
  {
    remainder = subtract(remainder, divisor);
    quotient = add(quotient, 1);
  }

  //求余的符号
  if(a < 0)
  {
    remainder = add(~remainder, 1);
  }

  return remainder;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值