1. 程式人生 > >使用位運算實現加減乘除

使用位運算實現加減乘除

在不使用+,-,*,/,四則運算子號的情況下,通過基本位運算實現加減乘除四則運算。

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;
}