C语言学习-原码、反码、补码
原码反码补码计算工具:一个工具箱
有符号位数据存储
计算机其实是以下面的式子来描述它的:(-1)^s乘X,这里的指数s就是用来决定数值X是正数还是负数,如图所示。
机器数:一个数在计算机中的二进制表示形式叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1。比如十进制中整数+3,若计算机字长为8位,转换为二进制数为 0000 0011;如果是-3,就是 1000 0011。
机器数+3 | 机器数-3 |
---|---|
0000 0011 | 1000 0011 |
原码、反码、补码
原码
原码是容易被人脑所理解的表达方式,它用第一位表示符号位,其余位表示值。因为第一位是符号位,所以8位二进制数的取值范围就是[1111 1111,0111 1111] 即[-127,127]。
原码+3 | 原码-3 |
---|---|
0000 0011 | 1000 0011 |
反码
反码的表示方法是正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各个位取反。
补码
补码的表示方法是,正数的补码就是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1(即在反码的基础上+1)。
+3原码、反码、补码
原码+3 | 0000 0011 |
---|---|
反码+3 | 0000 0011 |
补码+3 | 0000 0011 |
-3原码、反码、补码
原码-3 | 1000 0011 |
---|---|
反码-3 | 1111 1100 |
补码-3 | 1111 1101 |
计算数的运算
为了满足负数对加法的需求,就必须让负数与他对应的二进制码是同步递增或者同步递减。于是就通过符号位不变,其余位取反来满足这个同步递增或者递减的要求,由于正数本来就满足它本身的加法,所以不需要做任何改变,这就是反码的定义由来。
- 反码运算
1+(-1) = [0000 0001]反+[1111 1110]反=[1111 1111]反 =[1000 0000]原 =-0
****但反码计算减法,结果真值部分是正确的.而唯一的问题其实就出现在"0"这个特殊的数值上.虽然人们理解上+0和-0是一样的。为了解决0的符号以及两个编码的问题,于是补码出现了。
- 反码运算
1+(-1) =[0000 0001]补+[1111 1111]补=[0000 0000]补 =[0000 0000]原 =0
现在0用[0000 0000]表示,而以前出现问题的-0则不存在了,这样可以用[1000 0000]表示-128:(-1) +(-127) =[1111 1111]补 +[1000 0001]补 =[1000 0000]补。
-128没有原码与反码
-1-127的结果应该是-128,在用补码运算的结果中,[1000 0000]补 就是-128.但是注意实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示。