背景:
我偶然发现了C here中的按位运算符,现在我正在尝试更多地了解它们。我四处寻找练习并遇到了this。
但是,我无法理解第一个" bitAnd。"
代码为:
/*
* bitAnd - x&y using only ~ and |
* Example: bitAnd(6, 5) = 4
* Legal ops: ~ |
* Max ops: 8
* Rating: 1
*/
int bitAnd(int x, int y) {
/* NOR Equivelent of AND */
return ~(~x | ~y);
}
问题:
现在,我认为管道(|)意味着"或。"那么,为什么我们需要~x和~y?我们不能这样说:
int bitAnd(int x, int y) {
int or = x | y; //something is one number or the other
int and = ~or; // not or is the same as and
return and;
}
我为自己编写并运行了第二个代码示例(我有一个运行它的主函数)。我得到-8作为答案,但是对于值6和5,你应该得到4。 如果你有"或" (管道运营商)和"和"恰恰相反,或者,为什么我们需要使用"〜"在我们计算〜和?
之前的每个值 一些额外的信息/想法:
我理解"〜"翻转值中的所有位。 "或"如果存在,则将该位从任一值复制到另一个值(我从here了解到)。所以,如果我有:
6 = 00000110
和
5 = 00000101
我应该得到0000111。
我只是提到这一点,以显示我对某些操作的知识,以防我对这些操作的理解也是错误的。
答案 0 :(得分:4)
这是典型的逻辑门知识。 AND门的等价物不是NOR b。
让我们看看会发生什么。假设您有这样的值:
a = 00111 => 3
b = 01001 => 9
a AND b = 00001 => 1
这就是我们的期望。让我们通过您的共享方法运行它,第一个方法:
~a = 11000 => 24
~b = 10110 => 22
~a | ~b = 11110 => 30
~(~a | ~b) = 00001 => 1 as we expect.
现在,让我们运行你的第二个方法。
or = 01111 => 15
and = ~or = 10000 => 16.
现在你有问题了。从逻辑上讲,你所做的就是:
~(a | b) = ~a AND ~b.
这是真的吗?
~a = 11000 => 24
~b = 10110 => 22
~a AND ~b = 10000 => 16.
它同意我上面所说的,但是,你可以看到它是错误的。我们想要1而不是16.按位逆“〜”运算符是分布式的。它也颠倒了操作。所以“或”变成“和”而“和”变成“或”。我希望能把它搞清楚。
答案 1 :(得分:1)
您提供的解决方案使用de Morgan的规则,即not (A and B) = not A or not B
。由于您需要计算A and B
,因此您再次否定所有内容并获得:A and B = not (not (A and B)) = not (not A or not B)
。
现在,您还可以根据真值表来思考为什么这是真的以及为什么您的主张不是。我不会详细显示所有内容,但在您的解决方案中,当{A和B>为0时,not (A of B)
,结果为1,这与和操作不一致。