signed vs unsigned int in C

4

我是一个C语言初学者,需要快速澄清关于整数的问题。

当你将某些东西转换为 int 类型时,它是 32 位的,其中一半的位用于负整数。因此,如果您知道您只会使用正整数,那么将其转换为 unsigned int 类型应该最大化您的正整数位,因此在了解输出始终为正时更有意义。这是真的吗?

谢谢!


7
“half of the bits are allocated for negative integers”这句话不正确。实际上,数值范围的一半用于负数,但只使用了一个比特位来表示符号。 - Laurence Gonsalves
4个回答

8

半数比特用于负整数这个说法是不正确的,对于普通整数只有一个比特位用于符号。

然而,您的假设是正确的。如果您确定数字是正数,则使用unsigned int将允许您访问范围为[0,2^32)的数字,而常规int仅允许[-(2^31),2^31-1],因为您不需要负值,这会留下较少的正数。


请注意,我的答案假定整数为32位,尽管它也可能是16位或64位,但答案背后的主要思想仍适用于这些情况。 - amit
Amit,我一定是无知或愚蠢或两者兼备。你能否以十六进制表示法展示一个等于 2*32 的无符号 32 位整数?或者等于 2^16 的 16 位整数?或者等于 2^8 的 8 位整数?非常感谢你。我真的很感激。 - Pete Wilson
@PeteWilson:你无法到达2的32次方,这就是为什么我写的范围是[0,2^32)(不包括2的32次方),而不是[0,2^32](包括2的32次方)。注意在书写数字范围时,方括号和小括号之间的差异。 - amit
啊,好的。所以无符号整数的范围实际上是0到2的32次方减1。现在我明白了。我没有理解那个范围符号。 - Pete Wilson
1
@PeteWilson:是的。对于整数来说,[0,2^32) == [0,2^32-1] - amit
好的,我听说过很多关于“二进制补码”算术的内容。那么这个二进制补码是怎么运用的呢?如果最高位是1,那么这个数就是负数,所以0x80000002就是-2,对吗? - Pete Wilson

4

不是一半的位数,而是只有一个位,它可以转换成一半的值。也不是强制类型转换,而是声明:如果你强制类型转换某个东西,你正在重新解释它,这并没有给你额外的范围,它只会给你一个潜在的与原始用户意图不同的值。


3

仅使用一位来标识数字是正数还是负数。

转换为无符号数可能有意义,也可能没有。有时最好让调试器及其他工具显示负数,以便让您意识到您的数字已超出范围。

特别需要注意的是在比较无符号数时要小心 - 许多循环由于倒计时值是无符号的,而比较是 “<0” 导致无法终止。


+1 主要是因为最后一句话中的警示故事。 :) - sarnold

0

一个比特用于表示正负,而非一半。使用无符号数字可以让你拥有比有符号等价物更大两倍的正值范围。


它不是将你可以拥有的值的数量加倍,而是将你可以拥有的正值的数量加倍。 - amit
1
但是,当然,如果你需要那么多的值,你就已经处于危险的边缘了,最好知道自己在做什么。 - Hot Licks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接