9

我正在努力翻转 C int 变量中的位。我这样做是这样的:

input = 15;

input = ~input;

printf("%d", input);

但它总是显示为-16. 应该是0!如果15写成1111,为什么要返回10000?!这太让人抓狂了!有人能帮帮我吗!?

4

3 回答 3

16

由于int在您的系统上很可能是 32 位数字,因此所有位都被翻转,包括原始数字中无关紧要的零的位:

00000000000000000000000000001111

变成

11111111111111111111111111110000

这是一个负数: 的最高有效位15为零,因此1翻转时变为。

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

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

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

于 2012-08-23T03:33:49.513 回答
5

这是因为input由多于四位组成。如果我们假设它input是 a signed char,有 8 位(或一个字节),那么:

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

如您所见, 的 4 个更高的有效位input均为 0。在按位 NOT 操作 (~) 之后,我们有:

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

以前为零的四位现在是一,而现在是零。有符号变量中的最高有效位确定其符号(0 为正,1 为负)。因此,通过翻转位,符号已被反转。负数可以读作:

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

解析为打印的 -16。

如果您的作业是使用按位 NOT 将变量归零,请尝试将其声明input为 anunsigned char以避免担心符号位。然后,设置input2558 位变量可以保存的最大值(0xFF0b11111111)。

于 2012-08-23T04:06:02.427 回答
3

15是类型int。取决于有多大int,表示以15结尾1111,但它以一堆s开头。0

~操作员翻转所有;s(其中14 个)变为0s,0s(其中 N-4 个)变为1s。

于 2012-08-23T03:34:38.680 回答