我无法让 2-complement 计算工作。
我知道 C 编译 ~b 如果 b = 5,它会将所有位反转为 -6。但为什么?
int b=101,将所有位取反为 010,然后对于 2 个补码的符号,我只需添加 1,但它变为 011,即 3,这是错误的答案。
我应该如何用位反转运算符计算〜?
我无法让 2-complement 计算工作。
我知道 C 编译 ~b 如果 b = 5,它会将所有位反转为 -6。但为什么?
int b=101,将所有位取反为 010,然后对于 2 个补码的符号,我只需添加 1,但它变为 011,即 3,这是错误的答案。
我应该如何用位反转运算符计算〜?
实际上,这是 5 通常在内存中的表示方式(16 位整数):
0000 0000 0000 0101
当你反转 5 时,你翻转所有位以获得:
1111 1111 1111 1010
这实际上是十进制形式的 -6。我认为在您的问题中,您只是简单地翻转了最后三位,而实际上您必须考虑构成整数的所有位。
问题b = 101 (5)
在于您选择的二进制数字太少。
binary | decimal
~101 = 010 | ~5 = 2
~101 + 1 = 011 | ~5 + 1 = 3
如果你选择 4 位,你会得到预期的结果:
binary | decimal
~0101 = 1010 | ~5 = -6
~0101 + 1 = 1011 | ~5 + 1 = -5
只需 3 位,您就可以在 2 的补码表示中编码从 -4 到 +3 的整数。使用 4 位,您可以以 2 的补码表示形式对 -8 到 +7 的整数进行编码。
-6 被截断为 2,-5 被截断为 3 位 3。您至少需要 4 位。
正如其他人已经指出的那样,~
只需反转值中的所有位,因此~~17
= 17
。
~b
不是 2 补码运算。这是一个按位 NOT 运算。它只是反转数字中的每一位,因此~b
不等于-b
.
例子:
b = 5
binary representation of b: 0000 0000 0000 0101
binary representation of ~b: 1111 1111 1111 1010
~b = -6
b = 17
binary representation of b: 0000 0000 0001 0001
binary representation of ~b: 1111 1111 1110 1110
~b = -18
binary representation of ~(~b): 0000 0000 0001 0001
~(~b) = 17
~
简单地反转一个数字的所有位:
~(~a)=17 if a=17
~0...010001 = 1...101110 ( = -18 )
~1...101110 = 0...010001 ( = 17 )
仅当您想要否定一个数字(以获得 2-s 补码)时才需要添加 1,即从 17 中得到 -17。
~b + 1 = -b
所以:
~(~b)
等于~(-b - 1)
等于-(-b - 1) -1
等于b
事实上,~
反转所有位,如果你再做~
一次,它会反转回来。
我无法让 2 完成计算工作。我知道 C 编译 ~b 如果 b = 5,它会将所有位反转为 -6。但为什么?
因为您使用的是二进制补码。你知道什么是补码吗?
假设我们有一个字节变量(有符号字符)。这样的变量可以具有从 0 到 127 或从 -128 到 0 的值。
二进制,它的工作原理是这样的:
0000 0000 // 0
...
0111 1111 // 127
1000 0000 // -128
1000 0001 // -127
...
1111 1111 // -1
带符号的数字通常用圆圈来描述。
如果您了解上述内容,那么您就会明白为什么〜1等于-2等等。
如果你使用了一个补码,那么 ~1 将是 -1,因为一个补码使用带符号的零。对于用补码描述的字节,值将从 0 到 127 到 -127 到 -0 再到 0。
您将 b 声明为整数。这意味着 b 的值将存储在 32 位中,并且补码 (~) 将发生在 32 位字上,而不是您所做的最后 3 位。
int b=5 // b in binary: 0000 0000 0000 0101
~b // ~b in binary: 1111 1111 1111 1010 = -6 in decimal
最高有效位存储整数的符号(1:负 0:正),因此 1111 1111 1111 1010 是十进制的 -6。
相似地:
b=17 // 17 in binary 0000 0000 0001 0001
~b // = 1111 1111 1110 1110 = -18