C按位否定会产生负输出:

时间:2012-08-23 03:31:12

标签: c bit-manipulation

我真的很难翻转C int变量中的位。我是这样做的:

input = 15;

input = ~input;

printf("%d", input);

但它总是显示为-16。它应该是0!如果15写为1111,为什么它会返回10000 ?!这令人抓狂!有人可以帮帮我!?

3 个答案:

答案 0 :(得分:13)

由于您系统上的int很可能是32位数字,所以所有位都被翻转,包括原始数字中无显着的零:

00000000000000000000000000001111

变为

11111111111111111111111111110000

这是一个负数:15的最重要位为零,因此在翻转时会变为1

如果您只想保留原始数字的位,则需要在数字的重要位置屏蔽所有数字,如下所示:

printf("%d\n", input & 0xF);

AND0xF“切断”除最后四位之外的所有位。

答案 1 :(得分:5)

这是因为input由四位以上组成。如果我们假设inputsigned char,有8位(或一个字节),那么:

input == 15 == 0x0F == 0b00001111

正如您所看到的,input的4个更重要的位都是0.在按位NOT运算(〜)之后,我们有:

~input == -16 == 0xF0 == 0b11110000

以前为零的四位现在是1,而现在是零。有符号变量中最重要的位确定其符号(0表示正数,1表示负数)。因此,通过翻转符号,符号已被反转。负数可以理解为:

1      1     1     1     0     0     0   0
-128 + 64  + 32  + 16  + 0   + 0   + 0 + 0

解析为打印的-16。

如果您的作业是使用按位NOT将变量归零,请尝试将input声明为unsigned char,以避免担心符号位。然后,将input设置为255,即8位变量可以容纳的最高值(0xFF0b11111111)。

答案 2 :(得分:3)

15的类型为int。取决于int的大小,15的表示以1111结尾,但0 s开始

~运算符翻转所有位; 1 s(其中4个)变为0 s,0 s(其中4个)变为1 s。