# 原码、反码、补码和移码详解 # 原码、反码、补码和移码的“由来” |
您所在的位置:网站首页 › 补码转原码符号位变不变位 › # 原码、反码、补码和移码详解 # 原码、反码、补码和移码的“由来” |
一、原码、反码、补码和移码的一般求法
码制一般求法原码符号位用0表示正数,1表示负数,其余位不变。反码正数的反码与原码一样,负数的反码是对它的原码(除符号位外)各位取反。补码正数的补码与原码一样,负数的补码是其反码尾部加1。移码不管正负数,将其补码的符号位取反即可。
二、移码的“真正”求法
移码:移码表示法是在数X上增加一个偏移量来定义的,通常用于表示浮点数的阶码。 如果机器字长为n,规定偏移 量为2n-1,则移码定义如下: X 为纯整数:[X]移=2n-1+X(-2n-1≤X<2n-1) X 为纯小数:[X]移=1+X(-1≤X<1) 【举个栗子】 [+1]移=28-1+1=129=1 000 0001 [-1]移=28-1 -1=127=0 111 1111 [+127]移=28-1+127=255=1 111 1111 [-127]移=28-1 -127=1=0 000 0001 [+45]移=28-1+45=173=1 010 1101 [-45]移=28-1 -45=83=0 101 0011 [+0.5]移=1+0.5=1.5=1 100 0000 [-0.5]移=1-0.5=0.5=0 100 0000 [+0]移=[-0]移=1 000 0000 三、原码、反码、补码和移码的“由来” 1. 原码原码:符号位用0表示正数,1表示负数,其余位不变。 对于计算机,加减乘除是最基础的运算,要设计的尽量简单。 计算机辨别“符号位”显然会让计算机的基础电路设计变得十分复杂!于是科学家想出了将符号位也参与运算的方法。 我们知道,根据运算法则,减去一个正数等于加上一 个负数,即:1-1=1+(-1)=0,所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了。 在运算中,原码进行加法运算是没有问题的,但是在减法运算中会出问题,如:(D表示十进制) 1D-1D =1D+(-1)D =[0 000 0001]原+[1 000 0001]原 =[1 000 0010]原 =-2D 这个结果明显是错误的! 如果用原码表示,让符号位也参与计算,显然对于减法来说,结果是不正确的。这也就是为何计算机内部不使用原码表示一个数的原因。 所以为了解决原码做减法的问题,出现了反码。 2. 反码反码:正数的反码与原码一样,负数的反码是对它的原码(除符号位外)各位取反。 【举个栗子】 使用反码计算 1-1 过程如下: 1D-1D = 1D+(-1)D = [0 000 0001]原+[1 000 0001]原 =[0 000 0001]反+[1 111 1110]反 =[1 111 1111]反 =[1 000 0000]原 = - 0D 发现用反码计算减法,结果的真值部分是正确的。 而唯一的问题其实就出现在“0”这个特殊的数值上。虽然人们理解上+0 和-0 是一样的, 但在这里 0 带符号是没有任何意义的,而且会有[0 0000000]原和[1 0000000]原两个编码表示 0。 于是补码出现了,解决了 0 的符号和 0 的两个编码问题,以及原码和补码进行减法运算时出现的问题。 3. 补码补码:正数的补码与原码一样,负数的补码是其反码尾部加1。 使用补码计算 1-1 过程如下: 1D-1D =1D+(-1)D =[0 000 0001]原+[1 000 0001]原 =[0 000 0001]补+[1 111 1111]补 =[0 000 0000]反 =[0 000 0000]原 =0D 这样 0 用 0 000 0000 表示,而以前出现问题的-0 则不存在了,且在补码中 0 也只有一种唯一的表示形式。 假设机器字长为 8 位,使用补码则可以用[1 000 0000]补表示-128D; (-1)D+(-127)D =[1 000 0001]原+[1 111 1111]原 =[1 111 1111]补+[1 000 0001]补 =[1 000 0000]补 最终运算结果应为 [1 1000 0000]补,但由于机器字长为 8 位,最左边的“1”被丢掉了,故只剩下[1 000 0000]补。 -1-127 的结果应该是-128,在用补码运算的结果中,[1 000 0000]补就是-128。 但是注意因为实际上是使用以前的 -0 的补码来表示 -128,所以-128 并没有原码和反码表示(对-128 的补码表示[1 000 0000]补算出来的原码是[0 000 0000]原,这是不正确的)。 使用补码,不仅仅修复了 0 的符号以及 0 的两个编码的问题,而且还能够多表示一个最低数。这就是为什么 8 位二进制使用原码或反码表示的范围为[-127,+127],而使用补码表示的范围为[-128,127]的原因。 因为机器使用补码,所以对于编程中常用到的 32 位 int 类型,可以表示范围是(最高位是符号位):[-231,231-1],使用补码表示时可以多保存一个最小值 - 231。 假设机器字长为 n 位,则使用补码表示的最小的一个数是 -2n-1。 4. 移码移码:不管正负数,将其补码的符号位取反即可。 常用来比较大小,一般会把浮点数的阶码用移码表示。当把数值用移码表示出来可一眼看出它们的大小,这样很容易判断阶码的大小,移码可用于简化浮点数的乘除法运算。 四、原码、反码、补码和移码的取值范围 码制定点整数定点小数原码-(2n-1-1) ~ +(2n-1-1)-(1-2-(n-1)) ~ +(1-2-(n-1))反码-(2n-1-1) ~ +(2n-1-1)-(1-2-(n-1)) ~ +(1-2-(n-1))补码-2n-1 ~ +(2n-1-1)-1 ~ +(1-2-(n-1))移码-2n-1 ~ +(2n-1-1)-1 ~ +(1-2-(n-1))【定点小数的取值范围的推算】 以补码为例:一个数用 n 位存储,用掉一个符号位后,还有 (n-1) 位,如果小数点在最右边,此时表示的是整数,可表示 -2n-1 ~ +(2n-1-1) 范围的数,把小数点左移 n-1 位,相当于除以 2(n-1) ,结果为: -1 ~ +(1-2-(n-1)) 同理可以将其他码制的范围求出来。 【总结】总之,反码用来解决负数加法运算问题,将减法运算转换为加法运算,从而简化运算规则; 补码解决负数加法运算正负零问题,弥补了反码的不足。 反码与补码都是为了解决负数运算问题,跟正数没关系,因此,不管是正整数还是正小数,原码,反码,补码都全部相同。 将补码符号位取反即得到相应的移码。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |