想写一个很有意思的话题, 补码.
最早看到这个名词,是三年前自学韩顺平老师的java课程中学到的, 当时也浅浅地讲了位运算, 原码, 反码和补码的内容. 不过当时觉得并没有什么用, 练了练计算方式, 就把这个名词忘记了.
如今三年过去, 数理储备增进了一步, 在《深入理解计算机系统》里, 重新看到这个词, 又有新的理解路径.
所谓补码, 无非是弥补当年设计原码的漏洞. 原码只能处理加法逻辑, 甚至会造出+0和-0这对双生子. 从现在看来, 或许有时候会想骂一下脑子有泡的原码设计者, 为什么要设计这一个无用的编码方式. 不过想来, 比起1111 1101, 还是1000 0011更加可爱一点.
在韩顺平的java课程中, 我记得韩顺平老师也引入了反码的概念, 先把原码转换成反码, 再把反码转换成补码, 不过《深入理解计算机系统》的视频课程里, 好像没有提到这一点.
我很感叹补码的巧妙, 补码的关键就在于”补“, 就如同一个时钟, 我想从三点拨到两点, 当然可以直接逆时针拨一个小时. 可如果被禁止逆时针拨指针, 也可以顺时针拨十一个小时, 理论上来说会变成十四点, 但是时间超过十二点, 就“爆掉了”, 还是能得到两点.
因此补码运算时, 两个补码相加, 最高溢出的位被巧妙的扔掉了.
这在数学上应该是叫模运算吧. 时钟里, 模是12. 补码里, 对于一个字节, 模是256.
有时也真是感叹, 计算机, 一个完全由人类自己缔造的学问, 竟然如此的精密又广博.