要解决这个问题,您要做的第一件事就是弄清楚如何仅使用位运算符进行简单的算术运算。
例如,可以使用这种技术实现加法
int add(int a, int b) {
int c;
while (a != 0) {
c = b & a;
b = b ^ a;
c = c << 1;
a = c;
}
return b;
}
然后就是用加法做乘法:
int mult(int a, int b) {
int i = 0;
int c = 0;
while (i < b) {
c = add(c, a);
i = add(i, 1);
}
return c;
}
如果 b 是负数,这个乘法还不能工作,但是因为这看起来像是一个家庭作业问题,所以我将把它留给你作为练习。 ;)
编辑:
加法后,乘法很直观,但加法函数不是那么容易理解,所以我在这里解释一下。
假设您要添加两个数字,11010011 和 10101。通常的方法是将它们排列成这样:
11010011
+ 10101
您会注意到,当您将两个二进制数相加时,如果两个数的第 i 位为 1,则结果位为 0,并且 i 左侧的位有一个进位。
这个进位是代码中变量“c”存储的内容。
//...
c = b & a;
//...
c << 1;
//...
我们按位和 b 和 a 只得到 a 和 b 都为 1 的位,然后我们左移 1 得到进位位。
然后您可以查看 a 和 b 不同的位,即一个位是 1,另一个位是 0。在这种情况下,结果位将是 1,没有进位。
这就是这条线所存储的:
b = b ^ a;
上面的行基本上删除了 a 和 b 都为 1 的位(现在存储在 c 中)。
所以现在你有另外两个数字 b 和 c,你需要把它们加在一起。
首先让我们看看在循环的第一次迭代之后我们的示例处于什么位置
c = a = 00100010
b = 11000110
这可能还不完全明显,但 b 正在累积结果和。通过循环的更多迭代,更多的位被“添加”回b,进位再次存储在c中。从这个意义上说,您可以将 xor 运算符视为没有进位的加法运算。
这是该循环的第二次迭代:
c = a = 00000010
b = 11100100
第三次迭代:
c = a = 00000000
b = 11100110
现在 c (和 a) 为 0,所以没有更多的进位要添加。我们退出循环并返回 b。请注意,即使您继续循环,任何数字都不会改变。