资讯专栏INFORMATION COLUMN

数据的表示:原码、反码、补码、移码以及浮点数的运算

cnTomato / 1471人阅读

摘要:而相应的,科学家们又提出了补码这一概念。因此在计算机中,为了避免运算错误,都是采用的补码进行加减法运算。原码反码补码移码数值表示范围在开始了解数值的表示范围之前,我们先来了解下什么叫做定点。

前言

最近在备战软考,复习到数据表示方面相关的知识,所以在这里做一下记录,也方便大家参考。

什么是 R 进制

对于 R 机制,如果要实现与十进制的转换,则使用 按权展开法,其具体操作为:

R 进制数的每一位数值用 R k R^k Rk 的形式表示,即幂底数为 R,指数为 kk 与该位和小数点间的间距有关。当该位位于小数点左边时,k 则是该位和小数点之间数码的个数;而当该位维语小数点右边时,则 k 是负值,其绝对值为该位和小数点之间数码的个数加 1

比如二进制和十进制之间的转换: 10111.01 = 1 ∗ 2 4 + 1 ∗ 2 2 + 1 ∗ 2 1 + 1 ∗ 2 0 + 1 ∗ 2 − 2 10111.01 = 1* 2^4+1*2^2+1*2^1+1*2^0+1*2^{-2} 10111.01=124+122+121+120+122

再比如七进制和十进制之间的转换: 403.02 = 4 ∗ 7 2 + 3 ∗ 7 0 + 2 ∗ 7 − 2 403.02 =4*7^2+3*7^0+2*7^{-2} 403.02=472+370+272

进制之间的转换

  1. 十进制转 R 进制

使用 短除法,比如我们要将 100 100 100 转换为二进制数,则有如下过程,最终的结果为 1100100 B 1100100B 1100100B

  1. 二进制转八/十六进制

假设我们有一个二进制数 100010010011 100010010011 100010010011,如果我们要将其转换为八进制数,一个八进制数需要 8 个基数来表示,所以需要 3 位二进制来表示。那么转换过程如下,即对应的八进制数为 4223 O 4223O 4223O

而如果我们将要将其转换为十六进制数,一个十六进制数需要 16 个基数来表示,所以需要 4 位二进制来表示。则对应的转换过程如下,即对应的十六进制数为 893 H 893H 893H

码制

计算机中,无论我们要存储任何数据,它都会转换为二进制码进行存储。现在的计算机中,如果我们要进行加法运算操作,那么我们很容易实现,因为现在的计算机体系大多采用冯诺依曼所提出的经典计算机体系结构,其中就包含了加法运算器。但如果我们要进行减法运算,那么此时就犯难了。没有减法运算器,我们要如何实现减法运算呢?而针对这一问题,原码、反码、补码就产生了。我们常用这三种码来表示一个机器数,从而解决计算机做减法的问题。下面是几个数的实例( 0 0 0 的补码只有一种表现形式),下面就分别来看看几种不同表示法的具体知识。

1-1+0-0
原码 00000001 0000 0001 00000001 10000001 10000001 10000001 00000000 00000000 00000000 10000000 10000000 10000000
反码 00000001 00000001 00000001 11111110 11111110 11111110 00000000 00000000 00000000 11111111 11111111 11111111
补码 00000001 00000001 00000001 11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000
  1. 符号位

正式了解不同码制之前,我们先来看看符号位的定义。所谓符号位,是在内存中存放的最左边的一位,如果该位为 0 0 0,那么说明这个数表示的是正数;而假如该位为 1 1 1,那么就说明这个数表示的是负数。

  1. 原码

是一种最简单的机器数表示法,我们常用最高位来表示符号位,而用余下的其他位来存放该数二进制的绝对值。也即除开符号位之外,原码的数据位就是一个数的二进制绝对值表示。

在上面的示例中,我们发现,虽然 0 0 0 − 0 -0 0 的原码不一致,但是主要还是符号位的不同,我们再用上面的示例来进行运算:

0001 + 0010 = 0011 , 1 + 2 = 3 0001 + 0010=0011,1 + 2 = 3 0001+0010=00111+2=3

0000 + 1000 = 1000 , 0 + ( − 0 ) = − 0 0000 + 1000= 1000,0 + (-0)=-0 0000+1000=10000+(0)=0

0001 + 1001 = 1010 , 1 + ( − 1 ) = − 2 0001+1001=1010,1+(-1)=-2 0001+1001=10101+(1)=2

可以发现,如果我们只是进行正数之间的加法运算,是不会出现问题的。但一旦出现正负数相加的情况,就会导致错误结果,而这主要是因为符号位所引起。那有没有相应的解决办法呢?别着急,我们接下来去看看反码。

  1. 反码

虽然原码很简单,但是存在的最大问题在于如果一个数加上其相反数结果不为 0 0 0,即 1 + ( − 1 ) 1 + (-1) 1+(1) 的结果不为 0 0 0,为了解决这个问题,才有了反码的出现。而针对反码,这里也分为两种情况:

  • 如果一个数是正数,那么其反码和原码一样,如 1 1 1 的原码和反码均为 0001 0001 0001
  • 如果一个数是负数,那么其反码就是其原码除符号位之外,按位取反。如 − 1 -1 1 的原码为 1001 1001 1001,其反码为 1110 1110 1110

这个时候我们再来看看原码中存在的问题:

0001 + 1001 = 1111 , 1 + ( − 1 ) = − 0 0001+1001=1111,1+(-1)=-0 0001+1001=11111+(1)=0

可以看到通过使用反码,我们解决了源码中两个相反数之和不为 0 0 0 的情况,但是不是就代表我们可以用反码来进行通用减法运算呢?我们来试试两个不同的负数相加:

1110 + 1100 = 1010 , ( − 1 ) + ( − 3 ) = − 5 1110+1100=1010,(-1)+(-3)=-5 1110+1100=1010(1)+(3)=5

就离谱,这结果明显错误!所以反码还是不能彻底解决减法运算的问题。而相应的,科学家们又提出了补码这一概念。

  1. 补码

同样的,补码也很特殊,针对正负数也分为了两种情况:

  • 如果一个数是正数,那么该数的补码等于其原码,如 1 1 1 的原码和补码均为 0001 0001 0001
  • 如果一个数是负数,那么该数的补码等于反码 + 1 +1 +1,如 − 1 -1 1 的反码为 1110,那么其补码即为 1111

同样,我们来试试看反码中进行减法运算所出现错误的情况:

1111 + 1111 = 1110 , ( − 1 ) + ( − 1 ) = − 2 1111+1111=1110,(-1)+(-1)=-2 1111+1111=1110(1)+(1)=2

诶,完美解决了反码中两个负数相加时所出现的结果错误的情况。因此在计算机中,为了避免运算错误,都是采用的补码进行加减法运算。

  1. 不同码制之间的转换总结

经过上面的各种码制介绍之后,我们将一个数的不同码制之间的转换规律总结如下图:

  1. 移码

除开常用的原码、反码、补码之外,还有一种码制叫做移码。所谓移码,又叫做增码或者偏置码,它是在数 X X X 上增加一个偏移量来定义的,通常用来表示浮点数的阶码,其表示形式类似于补码,只是其符号位用 1 1 1 来表示正数, 0 0 0 来表示负数,则数值表示部分则是与补码相同。

1-1+0-0
原码 00000001 0000 0001 00000001 10000001 10000001 10000001 00000000 00000000 00000000 10000000 10000000 10000000
反码 00000001 00000001 00000001 11111110 11111110 11111110 00000000 00000000 00000000 11111111 11111111 11111111
补码 00000001 00000001 00000001 11111111 11111111 11111111 00000000 00000000 00000000 00000000 00000000 00000000
移码 10000001 10000001 10000001 01111111 01111111 01111111 10000000 10000000 10000000 00000000 00000000 00000000

数值表示范围

在开始了解数值的表示范围之前,我们先来了解下什么叫做定点。所谓定点,是因为小数点的位置是固定的,所以我们叫做数值是定点的整数或者小数。假如一个数值用码制的形式表示, 如果小数点在数值最低位(也即最后边)是,此时该数表示的是定点整数。但如果小数点在介于数值最高位和最低位的中间位置,那么此时该数所表示的就是一个定点小数。

码制定点整数定点小数
原码 − ( 2 n − 1 − 1 ) -(2^{n-1}-1) (2n11)~ + ( 2 n − 1 − 1 ) +(2^{n-1}-1) +(2n11) − ( 1 − 2 − ( n − 1 ) ) -(1-2^{-(n-1)}) (12

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/121251.html

相关文章

  • 【C语言进阶学习】一、数据存储 (深度剖析数据在内存中存储)

    摘要:的理解和区别代表有符号,整数在内存中存储的二进制位的最高位为符号位,表示负数,表示正数。那接下来我们来学习数据在所开辟的内存空间时如何存储的。请看下面例子为什么内存中存储的是补码对于整数来说数据存放内存中其实存放的是补码。 ...

    AprilJ 评论0 收藏0
  • 【C语言进阶】☀️数据类型&&整型在内存中存储

    目录 ​  一、数据类型介绍 二、类型的意义 三、类型的基本归类 整型家族 浮点数家族 构造类型(自定义类型) 指针类型 空类型 四、整形在内存中的存储 原码、反码、补码 大小端字节序 为什么有大端和小端? 一道经典笔试题  一、数据类型介绍 数据从大的方向分为两类: 内置类型自定义类型内置类型我们前面已经学习过,如下: char            //字符数据类型 short      ...

    Xufc 评论0 收藏0
  • 详解c语言整形和点数在内存中存储

    摘要:目录数据在计算机的存储方式补码,反码,原码数据在计算机的存储方式补码,反码,原码整形在内存中的存储整形在内存中的存储整形类型整形类型大端字节序和小端字节序大端字节序和小端字节序浮点数在内存的储存浮点数在内 目录 数据在计算机的存储方式(补码,反码,原码) 整形在内存中的存储:    整形...

    不知名网友 评论0 收藏0
  • 再识C语言(五)

    摘要:注不要移动负数位标准未定义行为这种行为属于标准未定义行为语言中并没有规定移动负数位。按进制位与规则两个二进制数,有则为,全则为。为假的时候,打印语言中表示假,非表示真无论是正数还是负数。 C语言操作符详解 目录 一、算术操作符 二、移位操作符 三、位操作符 四、赋值操作符 五、单目操作符 六...

    BigTomato 评论0 收藏0
  • C语言进阶第一问:数据在内存中是如何存储?(手把手带你深度剖析数据在内卒中存储,超全解析,码住不

    摘要:在符号位中,表示正,表示负。我们知道对于整型来说,内存中存放的是该数的补码。在计算机系统中,数值一律用补码来表示和存储。表示有效数字,。规定对于位的浮点数,最高的位是 ...

    ghnor 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<