为什么int的范围是-32768到32767? [关闭]

问题描述 投票:18回答:5

与正面相比,为什么任何数据类型的范围在负面都比较大?

例如,在整数的情况下:

在Turbo C中,它的范围是-3276832767,而对于Visual Studio,它是-21474836482147483647

其他数据类型也是如此......

[UPD:为Visual Studio设置适当的限制值]

c visual-studio int turbo-c
5个回答
39
投票

因为数字的存储方式。签名号码使用称为“二进制补码表示法”的东西存储。

请记住,所有变量都有一定的位数。如果它们中最重要的一个(左边的那个)是0,那么该数字是非负的(即正或零),其余的比特仅代表该值。

但是,如果最左边的位是1,则该数字为负。可以通过从表示的整数中减去2 ^ n来获得该数的实数值(作为无符号数,包括最左边的1),其中n是变量具有的位数。

由于只有n-1位留给数字的实际值(“尾数”),因此可能的组合是2 ^(n-1)。对于正数/零数,这很容易:它们从0到2 ^(n - 1) - 1.这个-1本身就是零 - 例如,如果你只有四种可能的组合,那么这些组合将代表0,1,2和3(注意有四个数字):它从0到4 - 1。

对于负数,请记住最左边的位是1,因此表示的整数介于2 ^(n - 1)和(2 ^ n) - 1之间(括号在那里非常重要!)。但是,正如我所说,你必须走2 ^ n才能获得该数字的实际值。 2 ^(n - 1) - 2 ^ n是 - (2 ^(n - 1)),并且((2 ^ n) - 1) - 2 ^ n是-1。因此,负数的范围是 - (2 ^(n - 1))到-1。

将所有这些放在一起,你得到-2 ^(n - 1)到2 ^(n - 1) - 1.正如你所看到的,上限得到-1,下限没有。

这就是为什么还有一个负数而不是正数。


15
投票

C所需的最小范围实际上是-32767到32767,因为它必须满足两个补码,负数的补码和符号/幅度编码,所有这些都是C标准允许的。有关数据类型的最小范围的详细信息,请参阅C11(和C99)的Annex E, Implementation limits

您的问题仅适用于两个补码变体,原因很简单。使用16位,您可以表示216(或65,536)个不同的值,零必须是其中之一。因此剩下奇数个值,其中多数(乘以1)为负值:

 1 thru  32767  = 37267 values
 0              =     1 value
-1 thru -32768  = 32768 values
                  -----
                  65536 values

两者的补码和符号幅度编码允许负零值(以及正零),这意味着非零数字可用一个较少的位模式,因此您在标准中找到的最小范围减小。

 1 thru  32767  = 37267 values
 0              =     1 value
-0              =     1 value
-1 thru -32767  = 32767 values
                  -----
                  65536 values

二进制补码实际上是一种漂亮的编码方案,因为正数和负数可以与相同的简单硬件一起添加。其他编码方案往往需要更复杂的硬件来执行相同的任务。

有关两个补码如何工作的更全面的解释,请参阅wikipedia page


1
投票

因为范围包括零。 n位整数可以表示的不同值的数量是2 ^ n。这意味着16位整数可以表示65536个不同的值。如果它是无符号的16位整数,则它可以表示0-65535(含)。有符号整数的约定代表-32768到32767,-214748368到214748367等。


0
投票

使用2s补码,负数被定义为按位而不是1,这将负数侧的给定位数中的可能数字的范围减少1。


0
投票

通常,由于使用二进制补码系统来存储负值,当您在整数上翻转符号位时,它会偏向负数。

范围应为: - (2 ^(n-1)) - ((2 ^(n-1)-1)

© www.soinside.com 2019 - 2024. All rights reserved.