码制
1024,谈谈码制
前言
本文记录于2024年1024程序猿节前夕。
1024,2的10次方,1k,多么美妙的数字。既然谈到数字,索性谈谈数字在计算机内的表示——码制
计算机的本质是电路,一般的电路有开、关两种状态。计算机用 0、1 分别表示这两种状态;0和1组成二进制数,进而可以通过这个计算机电路实现数的运算。虽然现代计算机的组成远远没有那么简单,已集成很多例如三极管等存在更多状态的元件,但数值在计算机内部的表示依然是二进制,这种表示形式称为机器数。
机器数分为无符号与带符号;无符号即正数,带符号则将最高位代表正或负。带符号的机器数可采用原码、反码、补码、移码等不同的编码方法,这些编码方法称为码制。
学习目标
- 了解数据在计算机内的表示:二进制
- 了解基础校验码
- 工作中很少直接用到,但可以应付考试
参考资料
1. 进制
常见进制字母表示:
- 二进制B
- 八进制O
- 十六进制H
任何进制数都可以用按权展开法转换为十进制。
例如:
10100.01B = 1*2^4+1*2^2+1*2^-2
十进制整数可通过短除法转换为相应进制,一般考十进制转二进制的较多,几乎不会考到或用到转其它进制。原理为按权展开的逆向。
进制常考点:十进制 与 二、八、十六进制之间的互相转换
1.1 二进制
十进制整数转二进制
短除法,取余数,结果余数倒排列;
十进制浮点数转二进制
整数部分按整数转二进制的方法算。小数部分乘以2取个位数,够1的取1,不够的取0,到达既定精度后顺序取即可。
例如:
//求 1.625D 的二进制表示
0.625D * 2 = 1.25 —— 1
0.25 * 2 = 0.5 —— 0
0.5 * 2 = 1 —— 1
将 整数部分 1 加上 ,最终结果为 1.101
1.2 八、十六进制
二进制转八进制:每3个二进制位对应一个八进制位;
二进制转十六进制: 每4个二进制位对应一个十六进制位;
当然也可以通过十进制为媒介相互转换。
1.3 浮点数
浮点数可表示为 N = M * R^e
M称为位数,e是指数,R为基数。
计算机中浮点数的运算,类似于十进制科学计数的运算,因为二进制,通常基数为2 ; 计算过程为 对阶——尾数计算——结果格式化。
2. 码制
2.1 常见编码
常见的编码通常要考虑符号位,因此下面介绍的几种编码方式均是带符号数。
- 原码 :这个数对应的二进制
- 反码 :正数的反码即原码,负数的反码是对应原码取反
- 补码 :正数的补码即原码,负数的补码是负数的反码+1,即对应正数的反码+1, 解决0的表示问题
- 移码 :补码+偏移量。通常偏移量为首位,即将符号位取反。为了解决数据在数轴的表示,通常用于浮点运算的阶码。
以上编码整数的表示范围:
- 原码 -(2^(n-1) -1) ~ 2^(n-1) -1
- 反码 同原码
- 补码 -2^n-1 - ~ 2^(n-1) -1
例题
8位二进制数的原码、反码、补码分别可表述数的范围是?
套用上述公式:
原码:-(2^7 -1) ~ 2^7 -1 , 即 -127 ~ 127
反码:-(2^7 -1) ~ 2^7 -1 , 即 -127 ~ 127
补码:-2^7 -1 ~ 2^7 -1 , 即 -128 ~ 127
2.2 校验码
检错与纠错
- 检错:检测出错误
- 纠错:纠正错误
主要方式:适当冗余。在硬件系统中,我们可以通过增大码距的方式实现检错与纠错
码距
一个编码系统的码距是整个编码系统中任意两个码字的最小距离。
例如:假设某个系统只有A和B两个值
- 若采用1位长度的二进制编码,A=0,B=1。A,B之间最小的码距为1。任意0或1都是合法编码,在计算机层面无法检错与纠错;
- 若采用2位长度的二进制编码,A=11,B=00。A,B之间最小的码距为2。只有11 和 00 是合法编码, 若出现10 或 01, 则说明已出错。
- 依此类推。
2.2.1 奇偶校验
奇偶校验码是最简单的校验码之一,增加一位校验位来使编码的1个数变为奇数或偶数,使码距变为2。
奇偶校验即在原有编码上增加一个校验位,之后,计算加上校验位后整个编码里1的数量是奇数或者偶数。但是要注意以下规则:
若原数据编码原本1的个数是奇数,则奇校验时校验位加的是0,偶校验校验位加的是1,使得加了校验位后1的个数依然是奇数或偶数;
若是原数据编码1的个数是偶数同理。
我们列个表举例就明白了:
原数据 | 奇校验 | 偶校验 |
---|---|---|
10110101 | 0(校验位) 10110101 | 1(校验位) 10110101 |
01001011 | 1 01001011 | 0 01001011 |
这样,在接收到传输的数据后,硬件就能通过1的个数来检查是否出错。
奇偶校验只能检测出1位错,而不能纠错。
常见的奇偶校验类型有:水平奇偶校验、垂直奇偶校验、水平垂直奇偶校验。
所谓水平、垂直,则是相对数据的列而言的,例如,上述列表举例的就是水平奇偶校验。
2.2.2 海明码
海(汉)明码的基础是奇偶校验。
下面介绍海明码的计算步骤:
确认校验位
海明码的校验位是根据原数据编码的位数决定的。
其校验位数 r 的计算公式为:
2^r >= 原数据位数 + r + 1
例如4位原数据1001
所需的校验位数是:
2^r >= 4+r+1
,即当 r >= 3 时,可满足上述不等式。一般我们取 r 的最小值即可。
具体校验位:
将2^k次幂留出来: 1,2,4,8,16,32 … ,作为校验位,如这里1001
的校验位为:
H7 | H6 | H5 | H4 | H3 | H2 | H1 |
---|---|---|---|---|---|---|
1 | 0 | 0 | 校验位4(2^2) | 1 | 校验位2(2^1) | 校验位1(2^0) |
先忽略我们尚未求得的海明码,假设我们已经完成了编码,此时,整个海明码为7位,下标从1开始算,我们可以求得上述表格H1~H7的海明码下标。
此时,我们可以将上述表格校验码的下标取出来:1,2,4。接下来,我们就对这个下标做一些处理,并求该校验位对应校验的是H几的编码:
求该校验位对应校验的海明码下标
1、2、4 对应的二进制分别为: 001、 010、 100, 其中的1代表要参与校验的编码下标的二进制在对应位置存在1。
我们分别求出原编码 H1~H7 的下标二进制:001、010、 011、100、101、110、111,于是:
H1 对应 校验: H1、H3、H5、H7
H2 对应 校验: H2、H3、H6、H7
H4 对应 校验: H4、H5、H6、H7
注意,校验的时候校验位也要一并算上去。
偶校验/异或求海明码
求得校验位对应要校验的编码下标后,我们就可以求具体的校验码了。
一般情况下,我们可以使用偶校验或者异或来求得。
例如,这里的 H1 = H3 ⊕ H5 ⊕ H7 = 0
同理,H2 = H3 ⊕ H6 ⊕ H7 = 0
H4 = 1
因此,1001 对应的 海明码 为 : 1001100
海明码纠错
查错:
我们将求得的海明码,加上自身进行异或操作,若得出的是0,则说明出错。(或者简单点数数该校验分组的1的总数是不是偶数,不是的话说明出错,校验位也算这个分组里面)
纠错:
海明码只能检测出2位错,纠1位错。
若已知只有1位出错,我们在对应的分组检测出错,那么需要再求出另外几个分组,将出错的分组 下标相加得出的和,即为具体出错的位置。将其取反,即可纠错。
2.2.3 循环冗余CRC
循环冗余CRC广泛应用于数据通信领域和磁介质存储系统中。
循环冗余CRC利用 生成多项式为 k 个 数据位产生 r 个校验位来进行编码, 其编码长度为 k + r 。
至于循环冗余CRC的具体原理和具体实现,在实际需要用到的时候再查阅具体资料即可,这里不深究。在应试和了解码制基础的层面,我们学会如何手算CRC即可。
考点
软考计算题
原始报文为11001010101,其生成多项式为 x^4 + x^3 + x + 1 。对其进行CRC编码后的结果为?
解题:原始报文补余数数量的0 ,生成多项式提取:11011;原始报文对生成多项式进行模2运算,最终余数就为CRC循环冗余该补的值。
将循环冗余的值补上报文,再对生成多项式进行模2运算,其结果余数应该为0。
3. 总结
码制是各种计算机考试中常考的点,也是计算机相关专业必学的知识,是基础。
本文主要记录我们需要掌握的码制基础知识:
- 进制,及其相互之间的转换;
- 常见编码:原码、反码、补码、移码;
- 经典校验码:奇偶校验码、海明码、循环冗余CRC
这里我们主要以文字描述的方式,介绍各码的基本概念、常见使用场景以及考试中可能会涉及的计算方式。若要应试,建议将本文作为参考,结合其它参考资料,然后刷题。
码制的概念在实际工作中,如果不是直接参与硬件相关的工作,或者一些特殊的计算,用得不多(或者来说我们可以不必过于关心具体码制、编码过程与硬件的计算)。但总的来说,了解一下,一来应试,二来可以稍微体会到这么多年来计算机设计与迭代过程中的一些巧妙之处,多少或许会给自己带来一些思考与知识拓展。