学习计算机原码、反码和补码的日记
今天花了半天学习计算机里的原码、反码和补码
首先得从基础概念入手,机器数和真值是绕不开的。机器数就是数字在计算机里的二进制形式,最高位是符号位,0代表正数,1代表负数,比如+3是00000011,-3是10000011。而真值就是机器数对应的真实数值,像10000011的真值是-3,不是它表面换算的131,这一步理解了,后面的编码才好展开。
接着就是核心的原码、反码、补码。原码最简单,符号位加真值绝对值,8位二进制里+1是00000001,-1是10000001,取值范围是[-127,127],人脑一看就懂,但计算机用它做减法会出问题。反码呢,正数和原码一样,负数是原码符号位不变、其余位取反,-1的反码是11111110,可它表示负数时没法直观读值,还会出现+0和-0两个编码,还是不够完美。
最后是补码,这才是计算机真正在用的。正数补码和原码相同,负数补码是原码符号位不变、其余位取反后加1,-1的补码是11111111。它解决了反码的0编码问题,让0只有00000000一种表示,还能多表示一个-128,8位二进制取值范围变成了[-128,127],32位int类型就是[-2³¹,2³¹-1],这一点之前一直没搞明白,今天终于通了。
最关键的是弄清楚为什么要用反码和补码。原来计算机设计时,想让运算更简单,只保留加法就好,因为减法可以转化成加负数。但原码直接算减法会出错,比如1-1用原码算会得到-2;反码算减法结果真值对了,却有两个0;补码完美解决了这些问题,1-1用补码算正好得0,符号位也能参与运算,不用额外设计识别符号的电路。
为了理解背后的数学原理,我还查了同余的概念。就像钟表,回拨2小时和往前拨10小时结果一样,因为它们关于模12同余。计算机里的反码、补码其实也是利用了同余,反码是对能表示的最大值取模,补码则是在此基础上加1,相当于增大了模的值,让运算结果总能落在正确的取值范围内。
不过数学证明部分还是有点绕,尤其是负数取模的计算,反复算了好几遍才明白。可能还有理解不到位的地方,以后遇到问题再慢慢琢磨吧。