可能的重复项:
如何仅使用位移位和加法进行乘法和除法?
我必须编写函数来执行二进制减法、乘法和除法,而无需使用除循环控制之外的任何算术运算符。我以前只用 Java 编写过代码,所以我很难解决这个问题。
从减法开始,我需要用原型写一个函数
int bsub(int x, int y)
我知道我需要将 y 转换为 2 的补码才能使其为负并将其添加到 x,但我只知道如何通过使用一个人的补码 ~ 运算符并加 1 来做到这一点,但我不能使用 + 运算符。
提供了 badd 函数,如果我能弄清楚如何将 y 设为负数,我将能够在 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 occurredn");
}
}
mask<<=1;
}
return result;
}
好吧,在没有+
或-
运算符的情况下按位运算中减法有点棘手,但可以做到。您对补语有基本的想法,但是不使用+
它变得有点棘手。
您可以通过首先仅按位设置加法来做到这一点,然后使用它,您可以进行减法。用于补码,所以代码看起来像这样:
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("%dn", bsub(53, 17));
return 0;
}
最终返回36
.这就是减法如何与仅按位运算一起工作。
除法变得更加复杂,但可以完成;对于这两个操作,使用移位以及加法和/或减法来完成工作。您可能还想阅读此问题和这篇有关如何执行此操作的文章。
你必须先实现二进制加法:
4 位示例:
a = 1101b = 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 来实现减法。
乘法的方式相同,但稍微困难一些。基本上这与你在学校学到的除法相同,使用掩码方便地选择位,并使用上面的加法添加中间结果。
除法有点复杂,需要更多的时间来解释,但基本上是相同的原理。