1

可能重复:
如何仅使用位移和加法进行乘法和除法?

我必须编写函数来执行二进制减法、乘法和除法,而不使用除循环控制之外的任何算术运算符。我以前只用 Java 编写过代码,所以我很难理解这一点。

从减法开始,我需要用原型写一个函数

int bsub(int x, int y)

我知道我需要将 y 转换为二进制补码才能使其为负并将其添加到 x,但我只知道如何通过使用补码 ~ 运算符并加 1 来做到这一点,但我不能使用 + 运算符。

提供了 badd 函数,如果我能弄清楚如何使 ya 为负数,我将能够在 bsub 中实现它。badd 的代码如下所示。提前感谢您的任何提示。

int badd(int x,int y){

int i;

char sum;
char car_in=0;
char car_out;
char a,b;

unsigned int mask=0x00000001;
int result=0;

for(i=0;i<32;i++){

  a=(x&mask)!=0;
  b=(y&mask)!=0;
  car_out=car_in & (a|b) |a&b;
  sum=a^b^car_in;

  if(sum) {
     result|=mask;
  }

  if(i!=31) {
     car_in=car_out;
  } else {
     if(car_in!=car_out) {
        printf("Overflow occurred\n");
     }
  }

  mask<<=1;
  }

 return result;
  }
4

2 回答 2

8

好吧,在没有+or-运算符的情况下进行按位运算的减法有点棘手,但可以做到。您对补码有了基本的想法,但不使用+它会变得有些棘手。

您可以通过首先仅按位设置加法,然后使用它来进行减法。用于补码,所以代码如下所示:

int badd(int n1, int n2){
    int carry, sum;
    carry = (n1 & n2) << 1; // Find bits that are used for carry
    sum = n1 ^ n2; // Add each bit, discard carry.
    if (sum & carry) // If bits match, add current sum and carry.
        return badd(sum, carry);
    else
        return sum ^ carry; // Return the sum.
}

int bsub(int n1, int n2){
    // Add two's complement and return.
    return badd(n1, badd(~n2, 1));
}

然后如果我们在一个例子中使用上面的代码:

int main(){
printf("%d\n", bsub(53, 17));
return 0;
}

最终返回36。这就是减法仅用于按位运算的方式。

之后乘法和除法变得更复杂,但可以完成;对于这两个操作,使用轮班以及加法和/或减法来完成工作。您可能还想阅读这个问题这篇关于如何做的文章。

于 2012-09-21T22:20:54.260 回答
-1

您必须先实现二进制加法:

4位示例:

a = 1101 b = 1011

掩码范围从 0001 到 1000

for (i=0;i<4;i++) {
    x = a & pow(2, i); //mask, you can shift left as well
    y = b & pow(2, i);
    z = x ^ y; //XOR to calculate addition
    z = z ^ carry; //add previous carry
    carry = x & y | x ^ carry | y ^ carry; //new carry
}

这是伪代码。掩码允许从左到右逐位操作。您必须方便地将 z 存储到另一个变量中。

一旦你有了加法,你就可以通过 1' 补加 1 来实现减法。

乘法也是如此,但稍微困难一些。基本上和你在学校学过的除法方法一样,使用掩码方便地选择位,并使用上面的加法添加中间结果。

除法有点复杂,需要花一些时间来解释,但基本上是相同的原理。

于 2012-09-21T22:22:51.520 回答