# 原码、反码、补码和移码详解 # 原码、反码、补码和移码的“由来”

您所在的位置:网站首页 补码转原码符号位变不变位 # 原码、反码、补码和移码详解 # 原码、反码、补码和移码的“由来”

# 原码、反码、补码和移码详解 # 原码、反码、补码和移码的“由来”

2024-07-12 09:05| 来源: 网络整理| 查看: 265

一、原码、反码、补码和移码的一般求法 码制一般求法原码符号位用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