为什么任何数据类型的范围在负面都比正面更大?
例如,在整数的情况下:
在 Turbo C 中,其范围为-32768
至32767
,对于 Visual Studio ,其范围为-2147483648
至{{1} }。
其他数据类型也是如此......
[UPD:为 Visual Studio设置正确的限制值]
答案 0 :(得分: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,下限没有。< / p>
这就是为什么还有一个负数而不是正数。
答案 1 :(得分:15)
C所需的最小范围实际上是-32767到32767,因为它必须满足两个补码,负数的补码和符号/幅度编码,所有这些都是C标准允许的。有关数据类型的最小范围的详细信息,请参阅C11(和C99)的Annex E, Implementation limits
。
您的问题仅适用于两个补码变体,原因很简单。使用16位,您可以表示2个 16 (或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。
答案 2 :(得分:1)
因为范围包括零。 n位整数可以表示的不同值的数量是2 ^ n。这意味着16位整数可以表示65536个不同的值。如果它是无符号的16位整数,则它可以表示0-65535(含)。有符号整数的约定代表-32768到32767,-214748368到214748367等。
答案 3 :(得分:0)
使用2s补码时,负数被定义为按位而不是1,这会将给定位数中可能数字的范围减少为负数。
答案 4 :(得分:0)
通常,由于使用二进制补码系统来存储负值,当您在整数上翻转符号位时,它会偏向负数。
范围应为: - (2 ^(n-1)) - ((2 ^(n-1)-1)