按位NOT运算符返回意外和负值?

时间:2013-12-22 11:22:50

标签: c++ c binary bit-manipulation

我正在尝试使用Bitwise NOT获取整数的值,但我没有达到我的预期。

#include <stdio.h>

int main(){
    int i = 16;
    int j = ~i;
    printf("%d", j);
    return 0;
}

不应该是16岁:

00000000000000000000000000010000

所以~16应该是:

11111111111111111111111111101111

为什么我没有达到我的预期,为什么结果是否定的?

这就是我想要做的事情:

我有一个例子27,例如:

00000000000000000000000000011011

如果它是1或0,想要检查每一位。

所以我需要得到这个值的例子

11111111111111111111111111110111

使用第二个来检查第一个的第3位是否设置为1.

4 个答案:

答案 0 :(得分:4)

虽然可以对编译器行为提出迂腐的观点,但简单的答案是顶部位设置的带符号的int是负数。

因此,如果你做了一些设置int的顶部位(有符号的int,而不是无符号的int),那么请求工具/库显示该int的值,你会看到一个负数。

这不是一个普遍的事实,但对于大多数现代系统来说,这是一个很好的近似。

请注意,这是在这里进行表示的printf - 因为%d将数字格式化为有符号。 %u可能会给出您期望的结果。只更改变量的类型是不够的,因为printf对其参数的类型一无所知。

我会说,作为一般的经验法则,如果你正在做一点点,那么使用无符号整数并以十六进制显示它们。生活会更简单,最符合意图。 (花哨的加速数学技巧是一个明显的例外)

答案 1 :(得分:1)

在二补码运算中得到一个反转数(对于检验[值为16得到值-16),你需要反转每一位并加1。

在你的例子中得到 - 16从16表示为

00000000000000000000000000010000

你反过来每个beit。你会得到

11111111111111111111111111101111

现在你必须加1,你会得到

11111111111111111111111111110000

正如你可以看到,如果你添加这两个值,你会得到0.它证明你做的都是正确的。

答案 2 :(得分:1)

如果你想得到一个数字的补码,你需要将这个数字放入一个无符号变量并显示它。 在C中它将是:

unsigned int x = ~16;
printf("%u\n", x);

您将获得4294967279。 但是如果你只是试图获得某一个的负数,那么把 - 运算符放在它之前。

编辑:要检查某位是0还是1,必须使用按位AND。

答案 3 :(得分:1)

  

如果它是1或0,想要检查每一位。

要检查单个位,您不需要数字,您和它使用适当的位掩码:

if ((x & 1) != 0) ... // bit 0 is 1
if ((x & 2) != 0) ... // bit 1 is 1
if ((x & 4) != 0) ... // bit 2 is 1
if ((x & 8) != 0) ... // bit 3 is 1
...
if ((x & (1 << n)) != 0) ... // bit n is 1
...
if ((x & 0x80000000) != 0) ... // bit 31 is 1