计算机系统中的数据表示
文章目录
数值编码
数据是计算机处理的对象。对于计算机处理数据,数据必须经过二进制编码才能被PC存储传输。
数据分为:
- 数值数据
- 非数值数据
- 结构化数据
- 非结构化数据
数值数据的编码
(1)进制转换
- B 2
- D 10
- O 8
- H 16
(2)定点数与浮点数
定点数:约定小数点的位置固定不变。有定点整数和定点小数(纯小数)。
浮点数:数符-阶符-解码数值部分-尾值数值部分
原码(定点数)
是机器数中最简单的一种表现形式。最高位是符号位,0表示正数,1表示负数
(1)整数原码
[ X ] 原 = { X 0 ≤ X < 2 n − 1 2 n − 1 − X − 2 n − 1 < X ≤ 0 {[X]_原}= \begin{cases}X& \text{$0\le X\lt {2^{n-1}}$}\\2^{n-1}-X & \text{${-2^{n-1}}\lt X\le {0}$}\end{cases} [X]原={X2n−1−X0≤X<2n−1−2n−1<X≤0
式中:X为真值,n-1为整数数值位的位数。
(2)小数原码(纯小数)
[ X ] 原 = { X 0 ≤ X < 1 1 − X − 1 < X ≤ 0 {[X]_原}= \begin{cases}X& \text{$0\le X\lt 1$}\\1-X & \text{$-1\lt X\le 0$}\end{cases} [X]原={X1−X0≤X<1−1<X≤0
补码
(1)整数补码
①对正数:与原码同。
②对负数:不包括符号位各位取反+1
(2)小数补码(纯小数)
①对正数:补码与原码相同。
②对负数:不包括符号位各位取反+1
(3)补码的特点
① 0 的表示唯一。
②变形码。模数为4时,形成双符号位的补码。eg. [ − 0.1001 ] 补 = 100 − 0.1001 = 11.0111 [-0.1001]_补=100-0.1001=11.0111 [−0.1001]补=100−0.1001=11.0111
③求补运算。包括符号位 全部 各位取反+1 求 补 ≠ 补 码 \color{red}求补\neq补码 求补=补码
④减法可以使用加法实现。
⑤算术或逻辑左移。左移一位,最高位(符号位)移出。最低位补0.
⑥算术右移。符号位不变,并将最高位的数据顺序右移一位,最低位移出。
【个人不是很能理解⑤⑥】
反码
反码通常用来作为由原码求补或补码求原码的中间过渡。
(1)整数反码
①对正数:与补码、原码同。
②对负数:将正数部分(包括符号位)按位取反。
(2)小数反码
同上。
(3)反码特点
① 0 有两种表示:0.0000000 or 1.1111111
②负数反码与补码:负数的补码=反码+1
③负数反码值 > 正数反码值
移码
在原来补码表示的编码上加上一个偏移量,就构成了移码。若是编码长度为8位,使用的偏移量为 2 7 2^7 27。
(1)特点
① 移码 = 真值 + 2 n − 1 2^{n-1} 2n−1
② 移码 <—取反—> 补码
③ 移码码值大小反映了数值的大小
④最高位符号位:1为正,0为负
⑤ 0 的移码唯一【1000 0000】、一一对应
不同编码的比较
- 真值为 + :原码、补码、反码的表示形式均相同。
- 真值为 - :原码、补码、反码的表示形式不同。
- 特殊的移码: 0 表示真值是负数; 1 表示真值是正数。
0有唯一的编码:补码、移码。
原码:1000 0000 | 0000 0000
反码:1111 1111 | 0000 0000
符号位用0表示正、用1表示负:原码、反码、补码
移码:1表示正、0表示负
满足真值大则码值大:移码
最高位符号位1为负数(真值小码值小):原码、反码、补码
存在负值的真值越大码值越小:原码
【-1】补=【1000 0001】补=【1111 1111】可见是:最大的负值、最大的码值。
反码 = 补码 - 1、移码 = 补码最高符号位取反 因此均不是。
负数的码值大于正数的码值:原码、反码、补码
原理是:负数的码值最高位符号位为1
数据的浮点表示
浮点数:小数点可以浮动的数。(比如用于科学计数法)
一般形式为: F = M × R E F = M \times R^E F=M×RE
M:尾数、可正可负
E:阶码、可正可负
R:基数(在计算机中可取2,4,8,16…)
表示范围
浮点数分为:非规格化浮点数以及规格化浮点数(有所不同)。
1)非规格化浮点数
①阶码 E 是整数,其位数 k 决定了浮点数表示的范围。
②尾数 M 是小数,其位数主要用于据欸的那个浮点数的精度。
③阶符决定阶码的正负、尾数的符号决定浮点数的正负。
2)规格化浮点数
通常,浮点数采用规格化形式来表示。
规格化:将位数的绝对值限定在一个规定的数值范围之内。当基值为2时,规格化浮点数尾数的绝对值应在 1 2 \frac {1} 2 21~1 之间。
要使尾数的绝对值在此范围内,通过改变小数点的位置(相应地改变阶码)即可做到。
通常会有两种错误:
- 上溢:浮点数的阶码大于最大阶码。此时机器会停止运算,进行溢出中断处理。
- 下溢:浮点数的阶码小于最小阶码。此时“溢出”的数绝对值很小。通常将尾数各位强制为 0 ,按机器零处理,机器继续运行。
一旦浮点数的位数确定后,不同的阶码和尾数尾数划分 会直接影响浮点数的表示范围和精度。所以要合理分配阶码和尾数的尾数。
3)规格化
在进行运算前和运算后,必须对其尾数规格化,使其成为规格化数。
当尾数不是规格化数使,就要通过修改阶码并同时左右移尾数使其变成规格化数。
将非规格化数 转为 规格化数 的过程叫规格化。
定点数与浮点数:
①当浮点计算机和定点计算机中数据的位数相同时,浮点数的表示范围比定点数大很多。
②当浮点数为规格化数时,其精度远比定点数高。
③浮点数运算要分阶码部分和尾数部分,而且运算结果要求规格化,故浮点运算步骤多,计算复杂,速度慢。
④对于溢出的判断:浮点数是对规格化数的阶码进行判断,而定点数是对数值本身进行判断。
IEEE754标准
IEEE754标准中规定float单精度浮点数在机器中表示用 1 位表示数字的符号,用 8 位来表示指数,用23 位来表示尾数,即小数部分。对于double双精度浮点数,用 1 位表示符号,用 11 位表示指数,52 位表示尾数,其中指数域称为阶码。
IEEE754规定:
单精度浮点数字长32位,尾数长度23,指数长度8,指数偏移量127;
双精度浮点数字长64位,尾数长度52,指数长度11,指数偏移量1023.
1:IEEE754单精度(32位)的二进制排列规则:符号位S(1位,0为正数,1为负数) + 阶码E(8位) + 尾数M(23位)
2:单精度的偏置常数为127(固定值),阶码 = 127 + 阶
计算
33.758 > 0 所以符号位S为0(转换为二进制:100001)
得到IEEE754的单精度浮点数格式为
符号位S(1位,0为正数,1为负数) + 阶码E(8位) + 尾数M(23位)
【 0 】 【1000 0100】【 0000 1110 0001 0000 0110 001】
BCD码
采用四位二进制编码来表示一位十进制数。
(1)有权码
8421、5421、2421、5211、4311码
运算以二进制编码计算但是可能会出现未定义的非法数据、因此要进行校正。
此处的非法数据指的是得到的结果并不是真正的计算出的正确结果。
但是我认为可以直接对十进制计算后再转化为BCD码,避免非法数据的产生。
(2)无权码:二进制各位没有确定的权值
余3码、格雷码。
非数值编码
ASCII码 (美国信息交换标准代码)
汉字编码
可分为三类:汉字输入编码、国际码、汉字内码以及汉字字模码。
汉字输入编码
拼音、字形、直接数字、整字编码、手写输入、语音输入。
国际码、汉字内码
国标码GB2312-80 《信息交换用汉字编码字符集(基本集)》。
汉字内部码是汉字在设备或信息处理系统内部最基本的表现形式。也是汉字在计算机内用于存储、检索、交换的信息代码。
与国标码有简单的转换关系:最高位是0则为ASCII码,1则为汉字内码。
汉字字模码
当汉字需要在屏幕上显示或需要在打印机上打印时,需要将机内码转换为汉字字形码。它表示汉字字形的字模数据,通常用点阵、矢量函数等方式表示。
检错与纠错码(考)
奇偶校验码
最简单且应用广泛的检错码是采用一位校验码的奇偶校验。
水平奇偶校验码
在其高位前增加一位奇(偶)校验位。 X = c x 0 x 1 ⋅ ⋅ ⋅ x n − 1 X=cx_0 x_1···x_{n-1} X=cx0x1⋅⋅⋅xn−1
(1)奇校验: c ⊕ x 0 ⊕ x 1 ⊕ ⋅ ⋅ ⋅ ⊕ x n − 1 = 1 {c}\oplus{x_0}\oplus{x_1}\oplus···\oplus{x_{n-1}}=1 c⊕x0⊕x1⊕⋅⋅⋅⊕xn−1=1 c ˉ = x 0 ⊕ x 1 ⊕ ⋅ ⋅ ⋅ ⊕ x n − 1 \bar c={x_0}\oplus{x_1}\oplus···\oplus{x_{n-1}} cˉ=x0⊕x1⊕⋅⋅⋅⊕xn−1
(2)偶校验: c ⊕ x 0 ⊕ x 1 ⊕ ⋅ ⋅ ⋅ ⊕ x n − 1 = 0 {c}\oplus{x_0}\oplus{x_1}\oplus···\oplus{x_{n-1}}=0 c⊕x0⊕x1⊕⋅⋅⋅⊕xn−1=0 c = x 0 ⊕ x 1 ⊕ ⋅ ⋅ ⋅ ⊕ x n − 1 c={x_0}\oplus{x_1}\oplus···\oplus{x_{n-1}} c=x0⊕x1⊕⋅⋅⋅⊕xn−1
总结:奇偶校验只能检验出1位出错。如果错误 ≥ 1 \ge 1 ≥1 ,就无法检测。但是由于其原理简单,实验起来非常容易,因此被广泛应用。
垂直奇偶校验码:把数据分成若干组,一组数据占一行,针对每一列采用奇偶检验。
水平垂直校验码:水平奇偶校验 + 垂直奇偶校验
海明码
海明码具有一位纠错能力。
根据编码纠错理论:任何一种编码是否具有检错能力和纠错能力,与编码的最小距离有关。
编码的最小距离:指在一种编码系统中,任意两组合法之间的最少二进制位数的差异。
对: L − 1 = D + C L-1=D+C L−1=D+C 且 D ≥ C D\ge C D≥C L ↑ ,D ↑ ,C ↑
(L : 编码最小距离 D : 检测错误的位数 C : 纠正错误的位数)
设欲检测的二进制代码为n位,为使其具有纠错能力,需添加k位检测位,组成n+k位代码。为了准确地对错误进行定位以及指出代码无错,对于k应满足: 2 k ≥ n + k + 1 2^k \ge n+k+1 2k≥n+k+1 。因此有下图所示:
n(代码长度) | k(最小) |
---|---|
1 | 2 |
2 ~ 4 | 3 |
5 ~ 11 | 4 |
12 ~ 26 | 5 |
27 ~ 57 | 6 |
58 ~ 120 | 7 |
海明码译码
其工作流程可以分为以下四个步骤:
(1)确定校验码位数r。
(2)确定校验码和数据的位置。
(3)求出校验码的值。
(4)检错并纠错。
eg. 在以下的工作流程中,我们要发送的数据D=101101.
工作流程
1、确定校验码位数r
我们使用海明不等式来确定校验码的位数r,海明不等式的形式如下: 2 r > = k + r + 1 2^r>=k+r+1 2r>=k+r+1
其中:k为数据的位数(信息位数);可以满足不等式的最小r为校验码的位数(冗余信息位数)
所以由海明不等式 2 r > = k + r + 1 2^r>=k+r+1 2r>=k+r+1 知:数据的位数为6位,校验码位数为4位。
2、确定校验码和数据的位置
在确定校验码P和数据D的位置的时候,我们的数据位按照1,2,3,…的顺序排布,按照下列原则:
(1)P1,P2,…,Pn:放在2的n(n>=0)次方的位置上.
(2)D1,D2,…,Dm:在校验码已经排放好的基础上,将D按序把剩下的空填满。注意:P的值暂放不填,将D的值按位填进去。
数据位 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
代码 | P1 | P2 | D1 | P3 | D2 | D3 | D4 | P4 | D5 | D6 |
实际值 | 1 | 0 | 1 | 1 | 0 | 1 |
3、求出校验码的值
首先,在步骤的表格基础上,加上数据位对应的二进制,更改后的表格如下:
二进制 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 |
---|---|---|---|---|---|---|---|---|---|---|
数据位 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
代码 | P1 | P2 | D1 | P3 | D2 | D3 | D4 | P4 | D5 | D6 |
实际值 | 1 | 0 | 1 | 1 | 0 | 1 |
接着按照如下的步骤操作:
(1)先找到P所对应的的二进制中1所在的位置
(2)再去看D中哪些数的对应位上的值也是1
(3)找到满足条件的D,再将P和这些D的实际值依次进行异或,令结果为等于0
(4)即可求出P(实际值)
按照以上步骤,可得:
P1⊕D1⊕D2⊕D4⊕D5=0 ⇒P1=0
P2⊕D1⊕D3⊕D4⊕D6=0 ⇒P2=0
P3⊕D2⊕D3⊕D4=0 ⇒P3=0
P4⊕D5⊕D6=0 ⇒P4=1
将P的值填入表中,得:
二进制 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 |
---|---|---|---|---|---|---|---|---|---|---|
数据位 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
代码 | P1 | P2 | D1 | P3 | D2 | D3 | D4 | P4 | D5 | D6 |
实际值 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 |
由此,我们可以得到101101的海明码为0010011101.
4、检错并纠错
在接收端,我们采用如下步骤进行判断所接收的数据串是否发生错误:
(1)按照前个步骤的做法。将P和对应的D(带入实际接收到值)进行异或
(2)将得到的结果按照倒序的方式进行排列
(3)排列好的结果,即数据出错位数的二进制值
(4)在找到出错位后,我们将其实际接收的值改为其相反的数即可。(1→0,0→1)
假设接收到的数据位0010111101,按照步骤进行判断。
P1⊕D1⊕D2⊕D4⊕D5=1
P2⊕D1⊕D3⊕D4⊕D6=0
P3⊕D2⊕D3⊕D4=1
P4⊕D5⊕D6=0
对应的位数的二进制表示为0101,即5。然后针对结果来判断是否出现差错。
正常情况下(也就是整个码字不发生差错的情况下)
- 在采用偶校验时,各校验组通过异或运算后的校验结果均应该是为0
(也就是前面所说的G1、G2、G3、G4,……均为0,因为此时1为偶数个,进行异或运算后就是0。)
- 而采用奇校验时,各组校验结果均应是为1。
所以应该是第五位 D2 发生了错误。取反得正确码:0010011101
注意:最终有多少个校验组出现差错也不是随意的,一定要结合实际传输的码字长度来考虑。
如上例是一共12位,如果换成了是16位的码字:
-
当D9位出现差错时,G1、G3、G4一定会同时出现错误,因为D9是三个校验组同时校验的,它出错会同时影响这三个校验组的值。
-
当D11位出现了差错,因为它同时受G1、G2、G3、G4四个校验组校验,所以这四个校验组结果都将出现错误。
循环冗余校验码(CRC码)
CRC码可以发现并纠正信息在存储或传送过程中出现地错误。基于%2运算(不考虑进位以及借位,感觉就是异或)。
由于不考虑进位以及借位,使得 %2 运算加法结果与减法相同。
%2 乘法运算没什么好说的,然后需要说一下的是商运算。
求商的规则:
个人认为书上写的很复杂,如下例子即可明白。
编码
为了得到K位校验位,则多项式需要K+1阶为最高阶。分为两步:
- 左移构成多项式
- 余数为检验码
译码及纠错
将收到的循环校验码用约定的生成多项式 G(x) 去除,如果无错,则余数应该为0;若某一位出错,则余数不为0。
不同的出错位对应不同的余数
可以验证,更换不同的待测码字,余数与出错位的对应关系不变,只与码制和生成多项式有关。
生成多项式的要求:
- 任何一位发生错误,都应该使余数不为0 。
- 不同位发生错误应该使余数不同。
- 对余数 %2 除,应使余数循环。
假设信息位是K,校验位是R,那么CRC的位数就是R + K 。而R是校验位,可以表示的数从 0 到 2 R − 1 2^{R-1} 2R−1 ,而0用来表示正确的情况,那么一共有2R-1种错误码,其中每个错误码对应一位,因此我们可以得到一个公式,当满足 2 R − 1 ≥ K + R 2^{R-1}\ge K+R 2R−1≥K+R的时候,CRC才具有纠错功能。
在R=3的情况下:发现余数是每7个一个循环,出错位1和出错位8的余数是一样的,出错位2和出错位9的余数是一样的,所以这也是为什么叫做循环冗余码的原因。【这里可能不太对???】
而一般我们不提及CRC的纠错功能。
因为CRC一般用在计算机网络中,在以太网的MAC帧中,通常4字节的效验码(FCS)不但用来检验MAC帧的数据部分,还用来检验目的地址、原地址和类型字段(60~1514)字节,信息位远远大于校验位,因此我们一般不提及CRC的纠错功能,但这并不代表没有。