c语言中int的范围为什么是-32768到32767?

一直以来都没搞懂,百度也不懂,希望大神能给我讲讲。假设int分配2个字节,就是16位,第16位表示正负 即1000 0000 0000 0000 第一位可以是0或1 第二位也一样..一直到第15位 所以一共是2的15次方+2的14次方...一直加到2的1次方 共32768, 又因为第一位最小是0,所以0-32767 就是32768个数 (正数我懂) 那么负数呢?不应该也是0到-32767吗? 为什么书上写的是 -32768~32767呢? 不应该是 -32767~32767吗? 负数的第一位,-0等于0啊

int 在内存中以补码的方式存在,且默认是有符号的,计算范围符号位为1的需要要转化为原码(其实都要转换,只不过符号位为0时原反补相同),转换方法减一取反。
要注意的:
1000 0000 0000 0001 -1=1000 0000 0000 0000 取反 1111 1111 1111 1111表示为-32767
1000 0000 0000 0000 -1 在计算机中检测到后不会做这个运算,而是默认为-32768
如果输入超出这个范围的如:32768
超出范围时,会以无符号的形式存入,但输出时是以有符号的形式输出
0111 1111 1111 1111(32767)+1=1000 0000 0000 0000以无符号存入, 输出以有符号形式,转换为原码就是-32768(如上)
int 是占四个字节,如果要测试的话,用short int(两个字节)
你的一个问题:1000 0000 0000 0000数值是32768超出范围了,你这样输入的时候就是无符号了。
还有二进制中是不会有2存在的

计算机中用补码存储,首位为0/1,其余位都为0时都可以表示零,补码可以将其中一个情况用来多表示一个数

因为负数用的补码形式存储,如果用反码存储的话就是你说的-32767~32767那种情况了

在计算机内部是用补码存储int的,正数的原码等于补码,而负数则不是,负数的补码为原码除符号位取反加1,我们认为的原码中定义负数最小值111111111111111,实际它是补码,转化为原码是10000000001,也就是-1,中间的位数我是乱敲的,可能不是16位,所以最小的负数用补码表示是10000000000,11000000000000,多出了一个最高位符号1。

假设int分配的是16位:
第十六位表示正负,那么按你的思路来,正数范围就是:
0000 0000 0000 0000(0) 到 0111 1111 1111 1111(32767),共32768个数
负数范围有:
1000 0000 0000 0000(-0)到1111 1111 1111 1111(-32767),共32768个数
然后关键来了,按照你的思路,就是现在最高表示就是-32767~32767了
但是注意看,这里表示0的编码有两个了,也就是表示0重复了
0000 0000 0000 0000(0)和1000 0000 0000 0000(-0)都是表示0了,而实际0只需要一个,所以这里直接理解成计算机强制用-0来表示最小的那一个,避免浪费,也就是1000 0000 0000 0000(-0)表示 -32768


// 0x8000,0x8001,...,0xFFFE,0xFFFF,0x0000,0x0001,...,0x7FFE,0x7FFF
//      |      |   |      |      |      |      |   |      |      |
// -32768,-32767,...,    -2,    -1,     0,     1,..., 32766, 32767