例如:
unsigned int i = ~0;
结果:我可以分配的最大数量i
和
signed int y = ~0;
结果:-1
为什么我会得到-1
?我不应该得到我可以分配的最大数量y
吗?
例如:
unsigned int i = ~0;
结果:我可以分配的最大数量i
和
signed int y = ~0;
结果:-1
为什么我会得到-1
?我不应该得到我可以分配的最大数量y
吗?
4294967295
(又名UINT_MAX
)和都-1
具有相同的二进制表示0xFFFFFFFF
或 32 位都设置为1
. 这是因为有符号数是用二进制补码表示的。负数的 MSB(最高有效位)设置为1
,其值通过翻转其余位、加1
并乘以 来确定-1
。因此,如果您将 MSB 设置为1
并且其余位也设置为1
,则翻转它们(获得 32 个零),添加1
(get 1
) 并乘以-1
最终得到-1
。
这使得 CPU 更容易进行数学运算,因为它不需要负数的特殊例外。例如,尝试添加0xFFFFFFFF
(-1) 和1
. 由于只有 32 位的空间,这将溢出,结果将0
如预期的那样。
更多信息请访问:
unsigned int i = ~0;
结果:我可以分配给 i 的最大数量
通常,但不一定。该表达式的~0
计算结果为设置了int
所有(非填充)位。C 标准允许有符号整数的三种表示形式,
~0 = -1
并将其分配给unsigned int
结果(-1) + (UINT_MAX + 1) = UINT_MAX
。~0
是负零或陷阱表示;如果它是负零,则分配给 anunsigned int
结果为 0。~0
是INT_MIN == -INT_MAX
,并将其分配给unsigned int
结果(UINT_MAX + 1) - INT_MAX
,1
在不太可能的情况下unsigned int
具有宽度(无符号整数类型的值位数,值位数 + 1 [对于符号位] 对于有符号整数类型)小于 的,int
并且2^(WIDTH - 1) + 1
在常见情况下 的宽度与unsigned int
的宽度相同int
。初始化
unsigned int i = ~0u;
将始终导致i
持有价值UINT_MAX
。
signed int y = ~0;
结果:-1
如上所述,只有当有符号整数的表示使用二进制补码时(这是迄今为止最常见的表示)。
~0
只是一个int
所有位都设置为 1。当解释为unsigned
这将等效于UINT_MAX
. 当解释为signed
这将是-1
.
假设 32 位整数:
0 = 0x00000000 = 0 (signed) = 0 (unsigned)
~0 = 0xffffffff = -1 (signed) = UINT_MAX (unsigned)
保罗的回答是绝对正确的。您可以使用以下命令,而不是使用 ~0:
#include <limits.h>
signed int y = INT_MAX;
unsigned int x = UINT_MAX;
现在,如果您检查值:
printf("x = %u\ny = %d\n", UINT_MAX, INT_MAX);
您可以在系统上看到最大值。
不,因为~
是按位 NOT运算符,而不是类型运算符的最大值。~0
对应于int
所有位设置为 的1
,将其解释为无符号为您提供无符号可表示的最大数,并解释为有符号的 int 为您提供 -1。
你必须在一个补码机器上。
查阅http://en.wikipedia.org/wiki/Two%27s_complement,了解一些关于布尔代数和逻辑设计的知识。还学习如何以二进制计数和二进制加减法将进一步解释这一点。
C 语言使用这种形式的数字,因此要找到您需要使用的最大数字 0x7FFFFFFF。(您使用的每个字节使用 2 个 FF,最左边的字节是 7。)要理解这一点,您需要查找十六进制数字及其工作方式。
现在解释无符号等价物。在有符号数中,数字的下半部分为负数(假设 0 为正数,因此负数实际上比正数高 1)。无符号数都是正数。所以理论上你的 32 位 int 的最高数字是 2^32,除了 0 仍然算作正数,所以它实际上是 2^32-1,现在对于有符号数,这些数字的一半是负数。这意味着我们将前一个数字 2^32 除以 2,因为 32 是一个指数,我们在每一边得到 2^31 个数字 0 为正数意味着有符号 32 位 int 的范围是 (-2^31, 2^31- 1)。
现在只比较范围: unsigned 32 bit int: (0, 2^32-1) signed 32 bit int: (-2^31, 2^32-1) unsigned 16 bit int: (0, 2^16-1)带符号的 16 位整数:(-2^15, 2^15-1)
you should be able to see the pattern here. to explain the ~0 thing takes a bit more, this has to do with subtraction in binary. it's just adding 1 and flipping all the bits then adding the two numbers together. C does this for you behind the scenes and so do many processors (including the x86 and x64 lines of processors.) Because of this it's best to store negative numbers as though they are counting down, and in two's complement the added 1 is also hidden. Because 0 is assumed positive thus negative numbers can't have a value for 0, so they automatically have -1 (positive 1 after the bit flip) added to them. when decoding negative numbers we have to account for this.