关于加法问题,试着运算1 - 1的值:
将1 - 1转换成1 + (-1)转换成二进制:00000001 + 10000001运算结果为10000010转换成十进制为-2
很明显,这个结果不对。为了解决这个问题,在计算机中引入补码(2's complement)来解决。要解释为什么要使用补码,还得从无符号整型开始说起。
为了便于理解和方便,我用 3 个字节的整数来讲解。但由于 C 语言最小都是 8 个字节,在代码验证方面使用 8 个字节。
无符号整型(unsigned integer)
3 个字节的无符号整型中,可以表示 2^3^ = 8 个数:
000 = 2^2 * 0 + 2^1 * 0 + 2^0 * 0 = 0+0+0 = 0 001 = 2^2 * 0 + 2^1 * 0 + 2^0 * 1 = 0+0+1 = 1 010 = 2^2 * 0 + 2^1 * 1 + 2^0 * 0 = 0+2+0 = 2 011 = 2^2 * 0 + 2^1 * 1 + 2^0 * 1 = 0+2+1 = 3 100 = 2^2 * 1 + 2^1 * 0 + 2^0 * 0 = 4+0+0 = 4 101 = 2^2 * 1 + 2^1 * 0 + 2^0 * 1 = 4+0+1 = 5 110 = 2^2 * 1 + 2^1 * 1 + 2^0 * 0 = 4+2+0 = 6 111 = 2^2 * 1 + 2^1 * 1 + 2^0 * 1 = 4+2+1 = 7
既然是整数,免不了要加减乘除。
在计算机中,只用加法可以完成的整数的四则运算:
减法,就是加上一个负数。乘法,就是不断的做加法。除法,就是不断的做减法,而减法又可以转换成加法。
但是这样会出现问题:
两个无符号整数相加,超出了 3 个字节表示的范围怎么办?比如:3 + 7。两个无符号整数相减。转换成加上一个负数。既然是无符号整数,哪里来的负数?
要想解决这个问题,抬头看看墙上的钟吧。
时钟系统
假设现在是 4 点钟:
但实际上现在已经六点钟了,你现在要把指针调到 6 点去。你可以这么做:
顺时针调整 2 个小时:
逆时针调整 10 个小时:
顺时针调整 14 个小时,逆时针调整 22 个小时…<