C按位否定会产生负输出:
我真的很难翻转C int变量中的位。 我是这样做的:
input = 15; input = ~input; printf("%d", input);
但它总是显示为-16
。 它应该是0
! 如果15
写为1111
,为什么它返回10000
? 这真令人发狂! 有人能帮帮我吗!?
由于系统上的int
很可能是32位数字,因此所有位都被翻转,包括原始数字中无效的零:
00000000000000000000000000001111
变
11111111111111111111111111110000
这是一个负数: 15
的最高有效位为零,因此在翻转时变为1
。
如果您只想保留原始数字的位,则需要在数字的重要位置屏蔽所有数字,如下所示:
printf("%d\n", input & 0xF);
AND
使用0xF
“切断”除最后四位之外的所有位。
发生这种情况是因为input
由四位以上组成。 如果我们假设input
是带有8位(或一个字节)的带signed char
,那么:
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位变量可以保持( 0xFF
或0b11111111
)。
15
是int
类型。 取决于int
大小, 15
的表示在1111
结束,但它从一堆0
开始 。
~
运算符翻转所有位; 1
s(其中4个)变为0
s, 0
s(N-4)变为1
s。