从32位有符号整数可表示的范围说起

2,429 阅读3分钟

这是我参与更文挑战的第 1 天,活动详情查看: 更文挑战

32位有符号整数可表示的范围是多少

众所周知,是 -231到231-1。有符号整数最高位用1或者0表示符号,剩下的31位表示数值

为什么负数比正数多一个

计算机中存储整数是用补码表示的

  • 十进制0是二进制00....00{32个0}

  • 正数的最高位是0,正数的范围是从00....01{32个0}011....111{31个1}

  • 负数的最高位是1,负数的范围是从10....0011....111

有一个最高位是0的二进制(00....00)用来表示十进制0了,不是正数,所以负数会比正数多一个

为什么要用补码表示

补码系统的最大优点是可以在加法或减法处理中,不需因为数字的正负而使用不同的计算方式。只要一种加法电路就可以处理各种有号数加法,而且减法可以用一个数加上另一个数的补码来表示,因此只要有加法电路及补码电路即可完成各种有号数加法及减法,在电路设计上相当方便

比如对于3-23 = 0011-1 = 1111,二进制表示就是0011 + 1111 = 1001010010显然是个负数,这里并不是算的不对,而是结果产生了溢出,本来只有4位,相加的结果是5位,这样的话就是直接去掉最高位,结果是0010 = 1

另外,补码系统的0就只有一个表示方式,如果只是简单的最高位是10来表示正负,那么0就有两种表示方式00....00或者10....00,这样不仅仅是一种浪费,并且要判断一个数是否等于0,就要比较两次了,要分别看它是不是00....00或者10....00

image-20210601185311965

上图是8位系统中整数的表示方式

补码到底是什么,为什么-128的补码是10000000

-128=10000000,是怎么得来的呢,如果按照我们教科书上的说法,负数的补码等于正数的反码加1(也又说符号位为1不变,剩下的反码加1),不管怎么说在8位系统下表示不了128,128应该等于010000000,这就是9位了

计算机是怎么区分无符号有符号的

  • 对二进制00000001,无符号数表示1,有符号+1

  • 对二进制10000001,无符号数表示129,有符号数表示-127

如果把他们相加得到1000010可以表示130,也可以表示-126

那么计算机是怎么区分这个数到底是有符号数还是无符号数呢,其实计算机并不区分有无符号。计算机只存储了这三个二进制数,是我们的编译器来区分数字的类型的,定义的是有符号的,print()的就是-126,定义的是无符号的,输出的就是130

参考

zh.wikipedia.org/zh-cn/%E4%B…