前置科普
计算机底层数据实际上是由0和1构成的,比如我们要存储一个十进制的3,那么就需要2个二进制位来保存,二进制格式为11,再比如我们要表示十进制的15,这时二进制的表现形式就为1111占用4个bit位。一般占用8个bit位来表示一个字节(用B表示),2个字节等于1个字,所以一个字由16个bit位构成。
我们经常说的电脑内存大小为8G、16G,实际上是按照下面的进制进行计算的:
8bit=1B,1024B=1KB,1024KB=1MB,1024MB=1GB,1024GB=1TB,1024TB=1PB(基本上是1024为一个大进位,但通常磁盘生产厂商是按照1000来换算的,所以我们买电脑的硬盘容量512G的到手实际容量会达不到实际的容量)
原码、反码和补码
原码
上面我们说了所有的数字都是使用0和1来表示的,但这样仅仅只能保存正数,那么负数怎么办?比如现在一共用4个bit位来保存我们的数据,为了表示正负,,我们可以用第一位专门来表示符号,这样4个bit位能够表示的数据范围就是:
- 最小:1111=>-(2^2+2^1+2^0)=>-7
- 最大:0111=>+(2^2+2^1+2^0)=>+7
虽然原码表示简单,但是原码在做加减法时,很麻烦,例如: 1+(-1)=0001+1001(这时虽然我们知道如何计算,但是计算机不知道,计算机最多知道1+1需要进位)
为了解决这个问题,于是我们引入了反码:
反码
正数的反码是其本身,负数的反码是其在原码的基础上,符号位不变,其余各个位取反,我们来看一组案例:
1+(-1)=0001+1110=1000=>0 (直接相加,就简单多了!)
注意:
正数的反码就是本身故为 0001
负数的反码是符号位不变,其他位取反,即 1001->1110
思考:1111代表-0,0000代表+0,在我们实数范围内,0有正负之分吗?
0既不是正数也不是负数,那么显然这样的表示依然不合理!
补码
根据上面的问题,我们引入最终解决方案,那就是补码,定义如下:
- 正数的补码就是其本身
- 负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1(即在反码的基础上+1)
我们再结合案例看一下:
1+(-1)=0001+1111=(1)0000=>+0(现在无论怎么算,都不会有-0了)
所以现在,4bit位能够表示的范围为:-8~+7