原码、补码、反码详解:LUKE 2017-11-13
1.原码:(True Form)*****************************************
是对计算机中的数字进行定点表示。最高位是符号位,其余为表示数值位。
注:
计算机中所有的数均用0,1编码表示,数字的正负号也不例外,如果一个机器数字长是n位的话,
约定最左边一位用作符号位,其余n-1位用于表示数值。
在符号位上用"0"表示正数;用"1"表示负数。数值位表示真值的绝对值。凡不足n-1位的,小数在
最低位右边加零;整数则在最高位左边加零以补足n-1位。这种计算机的编码形式叫做原码。
原码的优缺点:
优点:
简单直观;例如,我们用8位二进制表示一个数,+11的原码为00001011,-11的原码就是10001011
缺点:
原码不能直接参加运算,可能会出错。
例如数学上,1+(-1)=0,而在二进制中原码00000001+10000001=10000010,换算成十进制为-2。
显然出错了。所以原码的符号位不能直接参与运算,必须和其他位分开,这就增加了硬件的开销和复杂性
2.补码:*****************************************
注:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
特点:
1、一个负整数(或原码)与其补数(或补码)相加,和为模。
2、对一个整数的补码再求补码,等于该整数自身。
3、补码的正零与负零表示方法相同。
补码和原码的相互转换:
补码 -> 原码:
⑴如果补码的符号位为“0”,表示是一个正数,其原码就是补码。
⑵如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。
(最高符号位不变,数值位取反,再加1就是原码。)
原码 -> 补码:
⑴如果原码的符号位为“0”,表示是一个正数,其补码就是原码。
⑵如果原码的符号位为“1”,表示是一个负数,就是原码先减1,符号位不变,再数值位取反就是补码。
举例:-7 : 1000 0111(原码)
减1
1000 0110
符号位不变,再数值位取反
1111 1001(补码)
1111 1001(补码)
取反,
1000 0110
符号位不变,加1
1000 0111(原码)
-1.1 :1000 0001.0000 0001(原码)
减1
1000 0001.0000 0000
符号位不变,再数值位取反
1111 1110.1111 1111(补码)
1111 1110.1111 1111(补码)
符号位不变,再数值位取反
1000 0001.0000 0000
加1
1000 0001.0000 0001
(提示:代码中的小数点”.”是在书写时为了清晰起见加上去的,在机器中并不出现。)
(******提示:小数补码的简单计算方式:符号位保持不变,从右边起第一个1以及1右边的0保持不变,左边的数值位按位取反。)
补码的绝对值:
负数的补码的绝对值计算:只要对补码全部取反并加1,就可得到其数值。
举例:-65 = 1*2^6+1*2^0
1100 0001(原码)
减1
1100 0000
符号位不变,数值位取反
1011 1111(补码)
取绝对值:全部取反
0100 0000
加1
0100 0001(结果为:+65的补码)
补码的加减法(略,简单)
补码的乘法:
(等比数列求和公式)
a1 a2 a3...an
q = an / a(n-1)
an = a1 * q^(n-1)
Sn = a1 + a2 + ... + an = a1 * (1 - qn) / (1 - q) = (a1 - an * q) / (1 - q)
3.反码:*****************************************
反码是数值存储的一种,多应用于系统环境设置,如linux平台的目录和文件的默认权限的设置umask,
就是使用反码原理。在计算机内,定点数有3种表示法:原码、反码和补码。
所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。