数据的表示:原码反码补码移码以及浮点数的运算
Posted 村雨遥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据的表示:原码反码补码移码以及浮点数的运算相关的知识,希望对你有一定的参考价值。
前言
最近在备战软考,复习到数据表示方面相关的知识,所以在这里做一下记录,也方便大家参考。
什么是 R 进制
对于 R
机制,如果要实现与十进制的转换,则使用 按权展开法,其具体操作为:
将
R
进制数的每一位数值用 R k R^k Rk 的形式表示,即幂底数为R
,指数为k
,k
与该位和小数点间的间距有关。当该位位于小数点左边时,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=1∗24+1∗22+1∗21+1∗20+1∗2−2。
再比如七进制和十进制之间的转换: 403.02 = 4 ∗ 7 2 + 3 ∗ 7 0 + 2 ∗ 7 − 2 403.02 =4*7^2+3*7^0+2*7^{-2} 403.02=4∗72+3∗70+2∗7−2
进制之间的转换
- 十进制转
R
进制
使用 短除法,比如我们要将 100 100 100 转换为二进制数,则有如下过程,最终的结果为 1100100 B 1100100B 1100100B。
- 二进制转八/十六进制
假设我们有一个二进制数 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 |
- 符号位
正式了解不同码制之前,我们先来看看符号位的定义。所谓符号位,是在内存中存放的最左边的一位,如果该位为 0 0 0,那么说明这个数表示的是正数;而假如该位为 1 1 1,那么就说明这个数表示的是负数。
- 原码
是一种最简单的机器数表示法,我们常用最高位来表示符号位,而用余下的其他位来存放该数二进制的绝对值。也即除开符号位之外,原码的数据位就是一个数的二进制绝对值表示。
在上面的示例中,我们发现,虽然 0 0 0 和 − 0 -0 −0 的原码不一致,但是主要还是符号位的不同,我们再用上面的示例来进行运算:
0001 + 0010 = 0011 , 1 + 2 = 3 0001 + 0010=0011,1 + 2 = 3 0001+0010=0011,1+2=3
0000 + 1000 = 1000 , 0 + ( − 0 ) = − 0 0000 + 1000= 1000,0 + (-0)=-0 0000+1000=1000,0+(−0)=−0
0001 + 1001 = 1010 , 1 + ( − 1 ) = − 2 0001+1001=1010,1+(-1)=-2 0001+1001=1010,1+(−1)=−2
可以发现,如果我们只是进行正数之间的加法运算,是不会出现问题的。但一旦出现正负数相加的情况,就会导致错误结果,而这主要是因为符号位所引起。那有没有相应的解决办法呢?别着急,我们接下来去看看反码。
- 反码
虽然原码很简单,但是存在的最大问题在于如果一个数加上其相反数结果不为 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=1111,1+(−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 的原码和补码均为 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
诶,完美解决了反码中两个负数相加时所出现的结果错误的情况。因此在计算机中,为了避免运算错误,都是采用的补码进行加减法运算。
- 不同码制之间的转换总结
经过上面的各种码制介绍之后,我们将一个数的不同码制之间的转换规律总结如下图:
- 移码
除开常用的原码、反码、补码之外,还有一种码制叫做移码。所谓移码,又叫做增码或者偏置码,它是在数 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) −(2n−1−1)~ + ( 2 n − 1 − 1 ) +(2^{n-1}-1) +(2n−1−1) |
−
(
1
−
以上是关于数据的表示:原码反码补码移码以及浮点数的运算的主要内容,如果未能解决你的问题,请参考以下文章 |