原码:
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111],即:
[-127 , 127]
例如5和-5的原码:
00000000 00000000 00000000 00000101 //为5
10000000 00000000 00000000 00000101 //为-5
计算机中并没有减运算,减运算实际是加一个负数的运算,这也就是为什么正数之间的加运算会比减运算快的原因,减运算需要做更多的处理来让计算机解读成能理解的加运算,例如5-5计算机要处理成5+(-5),原码在高位用0和1解决了区分正负的问题,但是又引来的新的问题,因为我们都知道5+(-5)是等于0的,但是我们来看看原码之间的运算结果:
00000000 00000000 00000000 00000101+10000000 00000000 00000000 00000101
=10000000 00000000 00000000 00001010
10000000 00000000 00000000 00001010的原码并不是我们期待的0,而是-10,5+(-5)=-10这肯定不是我们要的结果,不仅如此原码正数高位为0,所有负数高位为1,这个时候会出现两个0的情况,一个为正0,一个为负0,这显然不太合理,0是没有正负的,为了解决第一个问题后来又引入了一个新的概念,那就是反码。
反码:
反码的表示方法是:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算。
一个正数和自身对应的负数的反码互为补数,因此减去该正数和加上该正数对应的负数的反码结果是一样的。
例如5和-5
00000000 00000000 00000000 00000101 //正数5和上面原码及普通二进制一样的表示
11111111 11111111 11111111 11111010 //-5的反码是5的二进制(或者说原码、反码都可以,因为都一样)0和1的反转
00000000 00000000 00000000 00000101+11111111 11111111 11111111 11111010
=11111111 11111111 11111111 11111111
这里的11111111 11111111 11111111 11111111是00000000 00000000 00000000 00000000的反码,所以是-0,这样反码的出现就解决了正负数字的运算问题,但是还存在一个问题,就是上面的0是两个,一个为正0,全为0,一个为负0,全为1。为了解决这个问题,又引入了补码的概念。
补码:
补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.
5的反码:00000000 00000000 00000000 00000101
5的补码:00000000 00000000 00000000 00000101
-5的反码:11111111 11111111 11111111 11111010
-5的补码:11111111 11111111 11111111 11111011 //就是在-5的反码基础上+1
00000000 00000000 00000000 00000101+11111111 11111111 11111111 11111011
=00000000 00000000 00000000 00000000 //5的补码+(-5的补码)=0且0没有正负号
总结:二进制不能表示负数,而原码虽然能表示负数,但无法进行正负数运算及两个0的问题,反码解决正负数运算的问题然后还保留着两个0的问题,只有补码完美解决了正负数运算问题同时还解决了两个不同符号的0的问题
最新评论