C 位操作逻辑(bitAnd)
C Bit Operation Logic (bitAnd)
背景:
我偶然发现了 C here, and now I am trying to learn more about them. I searched around for exercises and came across 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);
}
问题:
现在,我认为管道 (|) 表示 "or." 那么,为什么我们需要 ~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。
如果您有 "or"(管道运算符)和 "and" 正好相反的东西,或者,为什么我们需要在计算 ~ 和之前对每个值使用“~”?
一些额外的information/thoughts:
我知道“~”会翻转值中的所有位。 "Or" 将位从任一值复制到另一个(如果存在)(我从 here 中了解到)。所以,如果我有:
6 = 00000110
和
5 = 00000101
我应该得到 0000111。
我提到这个只是为了展示我对某些操作的了解,以防我对这些操作的理解也有误。
这是典型的逻辑门知识。 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。按位取反“~”运算符是分配的。它也反转操作。所以 "or" 变成了 "and" 而 "and" 变成了 "or"。我希望一切都解决了。
您提供的解决方案使用了 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)
.
现在,您还可以根据真值表来思考为什么这是真的以及为什么您的说法不是。我不会详细展示所有内容,但是在您的解决方案中,not (A of B)
当 A 和 B 都为 0 时,结果为 1,这与 and 操作不一致。
背景:
我偶然发现了 C here, and now I am trying to learn more about them. I searched around for exercises and came across 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);
}
问题:
现在,我认为管道 (|) 表示 "or." 那么,为什么我们需要 ~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。 如果您有 "or"(管道运算符)和 "and" 正好相反的东西,或者,为什么我们需要在计算 ~ 和之前对每个值使用“~”?
一些额外的information/thoughts:
我知道“~”会翻转值中的所有位。 "Or" 将位从任一值复制到另一个(如果存在)(我从 here 中了解到)。所以,如果我有:
6 = 00000110
和
5 = 00000101
我应该得到 0000111。
我提到这个只是为了展示我对某些操作的了解,以防我对这些操作的理解也有误。
这是典型的逻辑门知识。 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。按位取反“~”运算符是分配的。它也反转操作。所以 "or" 变成了 "and" 而 "and" 变成了 "or"。我希望一切都解决了。
您提供的解决方案使用了 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)
.
现在,您还可以根据真值表来思考为什么这是真的以及为什么您的说法不是。我不会详细展示所有内容,但是在您的解决方案中,not (A of B)
当 A 和 B 都为 0 时,结果为 1,这与 and 操作不一致。