ECE2050 Chapter 2 Number Systems 课堂笔记
本章在讲什么
计算机内部只能存 0 和 1,但我们日常生活用的是十进制,还经常接触八进制、十六进制。这一章的核心问题就是:数字在不同进制之间如何表示、如何转换、计算机如何用二进制做加减乘除、负数和小数如何表示、以及如何用编码来检错。整章逻辑就是沿着这条线推进的:先讲"数"怎么表示(Base-R 系统),再讲"数"怎么算(二进制算术),然后讲"负数"怎么表示(Two's Complement),接着讲"小数"怎么表示(Fixed/Floating-Point),最后讲几种特殊的二进制编码(BCD、Gray Code、ASCII、Parity、CRC)。
数制系统(Number Systems)
数制(number system)就是一套书写数字的符号系统。日常生活中人类不止用十进制:时间用 12 或 60 进制(12 小时制、60 秒一分钟),计数的"打"是 12 进制;而计算机系统里用的是 2、8、16 进制。
十进制(Decimal, Base-10)
十进制的三个要素:
- 基数(base)R=10;
- 数字符号(digit)只有 10 个:0∼9;
- 权重(weight):每一位的权重是 10x,从右往左依次是个位(100)、十位(101)、百位(102)……
以 537410 为例,它其实是一个加权求和:
537410=5×103+3×102+7×101+4×100=5000+300+70+4
也就是"五个千、三个百、七个十、四个一"。同一个数字符号 5 放在不同位置代表的值完全不同——这叫位置加权计数系统(positional/weighted number system),第 64 页会回到这个概念。
十进制还能表示小数,靠的是小数点(decimal point)右边那些权重小于 1 的位:
568.23=(5×102)+(6×101)+(8×100)+(2×10−1)+(3×10−2)=500+60+8+0.2+0.03
注意课件特别强调:在数字系统(digital systems)课程里,"decimal numbers" 指任何以 10 为底的数,而不只是"带小数点的数"。
Base-R 计数系统的通式
把十进制的规律推广到任意基数 R(要求 R≥2):
- 基数:R;
- 数字符号范围:[0,R−1](比如 base-5 只能用 0 到 4);
- 每一位的权重:Rx。
一个 N 位整数加 M 位小数的 base-R 数 (N)R=an−1an−2…a1a0a−1…a−m 的值是:
(N)R=an−1×Rn−1+an−2×Rn−2+…+a1×R1+a0×R0+a−1×R−1+…+a−m×R−m=i=−m∑n−1ai×Ri
每个符号的含义:ai 是第 i 位上的数字(必须满足 0≤ai≤R−1);Ri 是该位的权重;求和符号 ∑ 表示把每一位"数字 × 权重"的结果全部加起来。这个公式是整章的骨架——后面所有的"X 进制转十进制"都是直接套它。
常见的四种进制:十进制(base-10)、二进制(binary, base-2)、八进制(octal, base-8)、十六进制(hexadecimal, base-16)。
二进制(Binary Number System)
二进制的三要素:基数 R=2;数字只有 0 和 1(每个叫一个 bit,binary digit 的缩写);权重是 2x,小数点左边依次是 20,21,22…,右边是 2−1,2−2…
二进制转十进制
直接套通式。例:
(10.101)2=(1×21)+(0×20)+(1×2−1)+(0×2−2)+(1×2−3)=2+0+0.5+0+0.125=(2.625)10
小数点(binary point)右边第一位权重是 0.5,第二位 0.25,第三位 0.125,以此类推。
2 的幂(Powers of Two)
课件要求背熟 20 到 27:
20=1,21=2,22=4,23=8,24=16,25=32,26=64,27=128
这是二进制算术的基本功,后面所有转换和范围计算都会反复用到。
二进制计数(Counting in Binary)
二进制从 0 数到 7:0,1,10,11,100,101,110,111,对应十进制 0∼7。规律和十进制"个位数满 10 进 1"一样,二进制是"满 2 进 1",所以 1+1=10。
数制转换(Number Conversion)
二进制 → 十进制
直接按权重展开求和。例:(10011)2=1×16+0×8+0×4+1×2+1×1=1910。
十进制 → 二进制
有两种方法,考试都建议掌握。
方法一:凑最大幂(find the largest power of 2 that fits, subtract and repeat)。 以 5310 为例:不超过 53 的最大 2 的幂是 32=25,所以第 5 位是 1;53−32=21,不超过 21 的最大幂是 16=24,第 4 位是 1;21−16=5,最大可用幂是 4=22,第 2 位是 1;5−4=1,正好是 20,第 0 位是 1。没有用到的位(23,21)填 0:
5310=1101012(32+16+4+1=53)
方法二:反复除 2 取余(repeatedly divide by 2, remainder goes in next most significant bit)。 同样的 53:
- 53÷2=26 余 1
- 26÷2=13 余 0
- 13÷2=6 余 1
- 6÷2=3 余 0
- 3÷2=1 余 1
- 1÷2=0 余 1
把余数从最后一次往回读(第一个余数是最低位 LSD,最后一个是最高位 MSD),同样得到 1101012。
八进制(Octal, Base-8)
基数 8,数字 0∼7,权重 8x。八进制转十进制同样套通式:
(2374)8=(2×83)+(3×82)+(7×81)+(4×80)=1024+192+56+4=(1276)10
十进制转八进制用"反复除 8 取余"。例:35910:359÷8=44 余 7;44÷8=5 余 4;5÷8=0 余 5。第一个余数 7 是最低位(LSD),最后余数 5 是最高位(MSD),所以 35910=(547)8。
十六进制(Hexadecimal, Base-16)
基数 16,数字符号有 16 个:0∼9 加上字母 A 到 F,其中 A=10、B=11、C=12、D=13、E=14、F=15。十六进制转十进制:
(E5)16=(14×161)+(5×160)=224+5=(229)10
十进制转十六进制同样反复除 16 取余。例:65010:650÷16=40 余 10(即 A);40÷16=2 余 2;2÷16=0 余 8。所以 65010=(28A)16。
二进制 ↔ 八进制 ↔ 十六进制
这三种进制之间的转换不需要经过十进制,因为 8 和 16 都是 2 的幂:
- 八进制/十六进制 → 二进制:把每个八进制数字展开成 3 bit,每个十六进制数字展开成 4 bit。例:CF8E16=11001111100011102;75268=1111010101102。
- 二进制 → 八进制/十六进制:从最右边开始,每 3 bit(转八进制)或 4 bit(转十六进制)分成一组,每组换成一个数字;最左边不够一组的补前导 0(leading 0s)。例:1001100110102 按 3 位分组 100∣110∣011∣010 得 46328;11001010010101112 按 4 位分组 1100∣1010∣0101∣0111 得 CA5716。
之所以有人发明八进制和十六进制,是因为它们是表示大串二进制数的紧凑写法,且与二进制互转极其容易。实际应用:Linux 的文件权限用八进制,内存地址(memory address)用十六进制。
表示范围与单位
N 位数字能表示多少个数
N 位十进制数有 10N 种组合,范围 [0,10N−1]。例:3 位十进制数有 1000 种取值,范围 [0,999]。
同理,N 位二进制数(N-bit binary number)有 2N 种组合,范围 [0,2N−1]。例:3 bit 有 23=8 种取值,范围 [0,7],即 0002∼1112。"能表示 2N 个数"和"最大值是 2N−1"这两个结论后面反复出现,别混淆。
Bits, Bytes, Nibbles
课件里这页是填空题,答案如下:
- 1 个二进制位(bit)就是 1 bit;
- Nibble(半字节):4 bits,能表示 24=16 个值,范围 [0,15];
- Byte(字节):8 bits,能表示 28=256 个值,范围 [0,255];
- 1 个十六进制数字 = 4 bits = 1 nibble;
- 2 个十六进制数字 = 1 byte(这也是为什么十六进制这么常用:一个字节正好写成两个 hex 数字)。
在一个多位数里,最左边的位是最高有效位(Most Significant Bit, MSB),最右边是最低有效位(Least Significant Bit, LSB)。同理对字节有 most significant byte / least significant byte,对十六进制数也有 most/least significant digit。
大的 2 的幂与快速估算
210=1024≈103(1 kilo)、220≈106(1 mega)、230≈109(1 giga)、240≈1012(1 tera)、250≈1015(1 peta)、260≈1018(1 exa)。注意 kilo/mega/giga 在二进制语境下指 1024/1048576/1073741824,而不是恰好 1000 的幂。
快速估算技巧:把指数拆成 10 的倍数加余数。例如 224=24×220≈16×106=16 million;一个 32 位整数变量能表示的最大值约为 232=22×230≈4 billion(精确值 4294967296)。
为什么计算机用二进制
数字系统用固定数量的 bit 工作,而物理上最容易可靠区分的是两种状态(高/低电平、开/关),并且布尔逻辑(Boolean logic)与逻辑门(logic gates)天然就是围绕 0/1 建立的。课件推荐了 Crash Course Computer Science #3(Boolean Logic & Logic Gates)作为延伸材料。
二进制算术(Binary Arithmetic)
加法(Addition)
和十进制竖式一样,只是进位规则不同。加法规则(addition rules)四条:
- 0+0=0(和为 0,进位 0)
- 0+1=1(和为 1,进位 0)
- 1+0=1(和为 1,进位 0)
- 1+1=10(和为 0,进位 1)
例:1011+0011(即 11+3),从右往左逐位加,1+1 产生进位,1+1+1 产生和 1 进位 1,结果是 1110(即 14)。
例:1011+0110(即 11+6)= 10001(即 17)。注意结果变成了 5 bit——这就引出溢出问题。
溢出(Overflow)
数字系统用固定数量的 bit工作。当结果太大、现有的 bit 数装不下时,就发生溢出(overflow)。上面 11+6 用 4 bit 只能存下 0001(丢掉了最高位的进位),4 bit 无符号数最大只能表示 15,17 超出了范围。
减法(Subtraction)
减法规则四条:0−0=0;1−1=0;1−0=1;以及关键的 10−1=1,即 0−1 需要向高位借 1(borrow of 1)。例:101−011=010(即 5−3=2),个位 1−1=0,第二位 0−1 不够减、借位后变成 10−1=1,第三位 1−0(被借走后剩 0,实际是 0−0)= 0。后面会看到,计算机实际更常用"加负数"来实现减法。
乘法(Multiplication)
乘法规则极简:0×0=0,0×1=0,1×0=0,1×1=1(只有两数都是 1 结果才是 1)。手算竖式与十进制完全同构:乘数的每一位分别去乘被乘数,得到部分积(partial products),再把部分积错位相加。例:111×101:部分积为 111、000、111,错位相加得 100011(即 7×5=35)。
除法(Division)
二进制长除法(long division)与十进制同构。例:1001÷11(即 9÷3=3):商首位上 1,11;余 10,落下 0 得 100… 最终商 11 余 00。
有符号二进制数(Signed Binary Numbers)
到目前为止我们只处理了无符号数(unsigned)。要表示负数,有两种主流方案:原码(Sign/Magnitude)和补码(Two's Complement)。
原码(Sign/Magnitude Numbers)
规则很直观:最高位(最左边的 MSB)当符号位(sign bit),剩下 N−1 位表示数值大小。符号位 0 表示正数,1 表示负数。
例:4 位原码表示 ±6:+6=0110,−6=1110(只是把最高位从 0 改成 1)。
N 位原码的表示范围是:
[−(2N−1−1),2N−1−1]
(4 bit 就是 −7∼+7。)
原码有两个致命问题:
- 加法运算不工作。直接把 −6+6 的原码相加:1110+0110=10100,这不是 0,结果完全错误。也就是说用原码没法简单地把两个带符号数相加。
- 0 有两种表示:0000(+0)和 1000(−0),这会造成比较和判断上的麻烦。
补码(Two's Complement Numbers)
补码是现代计算机实际采用的方案,它没有原码的这两个问题:加法直接可用,且 0 只有唯一表示。
编码规则:最高位的权重规定为 −2N−1(注意是负的权重!),其余位照常是正权重。因此:
- 4 位能表示的最大正数:0111=0+4+2+1=+7(最高位为 0,负权重没生效);
- 4 位能表示的最小负数:1000=−8+0+0+0=−8。
最高位仍然天然指示符号(1 = 负,0 = 正),这点和原码一样。N 位补码的表示范围:
[−2N−1,2N−1−1]
(4 bit 是 −8∼+7;8 bit 是 −128∼+127。)注意负数端比正数端多一个数——因为 0 只占一个编码,省下的编码给了负数端。负数区域从 11111111=−1 一直排到 10000000=−128,负数的绝对值越大,编码看起来越"小"。
取负(Reversing the Sign)
把一个补码数变成它的相反数,方法两步:
- 按位取反(invert the bits,0 变 1、1 变 0);
- 加 1(add 1)。
例:310=00112,取反得 1100,加 1 得 1101=−310。
历史层面这个操作一直叫 "taking the two's complement"(求补码),但这个说法容易和"补码"这种表示法本身混淆,课件明确说课程里统一叫"reversing the sign"(取负/变号)。
例:610=01102 → 取反 1001 → 加 1 → 10102=−610。
反过来也可以用来解读一个负数:问补码数 10012 的十进制值是多少?它最高位是 1,是负数。取反得 0110,加 1 得 0111=7,所以 1001=−7。
补码加法(Two's Complement Addition):三步法
- 把十进制数转成二进制,负数用补码形式表示(用上面的取负方法生成);
- 做二进制加法;
- 判断符号:两数同正则结果应为正,两数同负则结果应为负;如果结果的符号不对,说明发生了溢出。
例(两正数):5+9:00000101+00001001=00001110=14,两正数结果为正,正确。
例(两负数,8 bit,范围 [−128,+127]):−125+(−58),即 10000011+11000110=101001001。第 9 位的进位超出 8 bit 被丢弃后结果是 01001001,是正数——两负数相加结果却为正,符号错误,溢出发生了(正确答案 −183 超出 8 bit 范围)。
例(一正一负):6+(−15):00000110+11110001=(1)00000111=7。这里最高位冒出的进位(carry)丢弃即可,有进位说明结果是正数;结果 +7 正确。而 8+(−16)=00001000+11101000=11101000,没有产生进位,说明结果是负数;11101000 取负验证:取反 00010111,加 1 得 00011000=24,所以结果是 −24,正确。
补码减法(Subtraction)
减法不用新规则:减去一个数等于加上它的相反数,即 A−B=A+(−B),其中 −B 用取负方法得到。
例:3−5=3+(−5):0011+1011=1110,无进位说明是负数,1110=−2,正确。
例:8−3=8+(−3):1000+1101=10101,丢弃最高位进位(discard the carry)得 0101=5,正确。在补码加法里,最高位冒出的进位直接丢掉即可,不影响结果正确性——这是补码设计最巧妙的地方。
补码乘法与除法
乘法(multiplication)两种做法:
- 直接累加(direct addition):把乘数那么多个被乘数连加。缺点是乘数很大时极其低效,且要求两数都用真值(true, uncomplemented)形式。
- 部分积法(partial product):同普通二进制乘法竖式,但先按无符号算出乘积,再定符号——同号得正,异号得负(same sign → positive; different signs → negative)。例(EXAMPLE 2–22):83×(−59):先算 01010011×01101101(即 83×59=4897=100100110100012),因为异号,对乘积取补码得 −4897。
除法(division)在计算机里用反复减法实现(EXAMPLE 2–23):100÷25(01100100÷00011001)。把除数 00011001 取负得补码形式 11100111,然后不断"加这个负数"(即不断减 25):
- 每成功减一次(余数仍 ≥0),商(quotient)加 1;
- 当余数(remainder)变为 0 或负数时停止;
- 商的值 = 减法执行的次数。本例减了 4 次,100−25×4=0,商 =4=01002。
商的符号规则同样:同号得正,异号得负。课件留了思考题:100÷(−25) 该怎么处理?——先按 100÷25 得商 4,再因异号取负得 −4。
三种表示法对比(Number System Comparison)
| Number System | Range(N 位) |
|---|---|
| Unsigned | [0,2N−1] |
| Sign/Magnitude | [−(2N−1−1),2N−1−1] |
| Two's Complement | [−2N−1,2N−1−1] |
以 4 bit 为例画在数轴上最直观:无符号编码 0000∼1111 覆盖 0∼15;补码把 1000∼1111 这一半解释为 −8∼−1,0000∼0111 解释为 0∼7;原码类似但 1000 和 0000 都代表 0,且 1111∼1001 对应 −7∼−1。同样的 bit 串,在不同表示法下含义完全不同——这是本章最重要的 takeaway 之一。
带小数的数(Numbers with Fractions)
前面只处理了整数。要表示分数(fractions),有两种常用记法:定点数(fixed-point,二进制小数点位置固定)和浮点数(floating-point,小数点浮动)。
定点数(Fixed-Point Numbers)
原理:在整数位和小数位之间约定一个"隐含的二进制小数点"(binary point is implied)。例:用 4 位整数 + 4 位小数表示 6.75:
存储:01101100⇒0110.1100⇒22+21+2−1+2−2=4+2+0.5+0.25=6.75
关键是:整数部分和小数部分各占多少位,必须事先约定好,否则同一个 bit 串会被解读成完全不同的数。
无符号定点格式 Ua.b:共 a+b 位,a 位整数、b 位小数。同一个数 6.75 在不同格式下的编码完全不同:
- U4.4:0110.1100 → 01101100
- U3.5:110.11000 → 11011000
- U6.2:000110.11 → 00011011
常用的定点宽度是 8、16、32 位。典型应用:U8.8 常用于传感器数据、音频、像素值;U16.16 用于更高精度的信号处理。
有符号定点格式 Qa.b:用补码表示,a 位整数部分(含符号位)、b 位小数。取负方法与整数补码一致:按位取反,然后给最低位(LSB)加 1。例:把 −6.75 写成 Q4.4:6.75=01101100 → 取反 10010011 → 加 1 得 10010100。典型应用:Q1.15(常简写 Q15)用于信号处理,能表示的范围是 (1,−1]。
饱和运算(Saturating Arithmetic):定点溢出通常很糟糕,会产生难看的伪影(artifacts):视频里明亮区域中间出现暗像素,音频里出现咔哒声。解决办法之一是饱和运算:溢出时不回卷,而是钉在最大值上。例:U4.4 下 11000000+01111000(即 12+7.5=19.5,超出了 U4.4 最大值 15.9375),饱和运算直接给出 11111111=15.9375,而不是溢出后的错误结果。
浮点数(Floating-Point Numbers)
定点数的问题:表示范围和精度被格式锁死。浮点数借鉴十进制的科学记数法(scientific notation):273=2.73×102。一般形式:
±M×BE
其中 M 是尾数(mantissa),B 是底数(base),E 是指数(exponent)。二进制浮点数的规则是:二进制小数点浮动到最高有效 1 的右边,即规格化为 1.xxxx×2E 的形式。
IEEE 754 单精度浮点标准(32-bit)
32 bit 分成三个字段:
- 1 bit 符号位(sign):0 正 1 负;
- 8 bits 指数(exponent):存"带偏移指数"(biased exponent);
- 23 bits 尾数(mantissa/fraction):只存小数点后的分数位。
两个关键设计:
- 隐含前导 1(implicit leading 1):规格化后尾数的首位永远是 1(例如 22810=111001002=1.11001×27),既然永远是 1 就没必要存,23 bit 字段只存 11001 后面补零的分数位——相当于白赚 1 位精度。
- 带偏移指数(biased exponent):实际存的值 = bias + 真实指数,单精度 bias =127(011111112)。例如指数 7 存为 127+7=134=100001102。这样 8 bit 无偏范围 [−127,+128] 被平移成 [0,255],可以只用无符号比较来比较指数大小,同时让极大数和极小数都能表示。
例 1:22810 的 IEEE 754 表示。228=111001002=1.11001×27;符号位 0;指数字段 127+7=134=10000110;尾数字段 11001000000000000000000。拼起来:01000011011001000000000000000000,写成十六进制即 0x43640000。
例 2:把 −58.2510 写成 IEEE 754,标准四步:
- 把数值部分的绝对值转成二进制:58.2510=111010.012(0.25=2−2);
- 写成二进制科学记数法:1.1101001×25;
- 填三个字段:符号位 1(负数);指数字段 127+5=132=100001002;23 位尾数 11010010000000000000000;
- 拼接:11000010011010010000000000000000,十六进制为 0xC2690000。
浮点特殊值(Special Cases)
| Number | Sign | Exponent | Fraction |
|---|---|---|---|
| 0 | X | 00000000 | 全 0 |
| +∞ | 0 | 11111111 | 全 0 |
| −∞ | 1 | 11111111 | 全 0 |
| NaN(Not a Number) | X | 11111111 | 非 0 |
即指数全 0 且尾数全 0 表示 ±0;指数全 1 表示无穷大(尾数 0)或 NaN(尾数非 0,比如 0/0 这类未定义运算的结果)。
特殊二进制编码
最后一部分回到更宏观的视角:并非所有二进制串都是用来做算术的"数",有些只是编码(code)。
位置加权 vs 非位置编码
位置/加权计数系统(positional/weighted number system):符号的值由它的位置决定,十进制、二进制、八进制、十六进制都是。非位置/非加权系统(non-positional/non-weighted):符号的值与位置无关,例子有格雷码(Gray code)、循环码(cyclic code)。
二进制编码十进制(Binary Coded Decimal, BCD)
BCD 的想法:把每一个十进制数字单独用一个 4 位二进制编码表示。最常用的是 8421 码(权值从高到低是 8、4、2、1):
| 十进制数字 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| BCD | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
注意 BCD 不等于二进制转换:17010 的 BCD 是 000101110000(1→0001,7→0111,0→0000),而它的二进制是 10101010。246910 的 BCD 是 0010010001101001。
BCD 转十进制:从最右边开始,每 4 位分成一组,每组查表还原为一个十进制数字。
BCD 加法三步:
- 先按普通二进制加法规则把两个 BCD 数相加;
- 若某个 4 位组的结果 ≤9,它是合法 BCD,直接保留;
- 否则(结果为 1010∼1111,或产生了进位),给这个 4 位组加 6(0110)。
例:9+4:1001+0100=1101,1101>9 不合法,加 0110 得 00010011,即 BCD 的 13,正确。
为什么要加 6? 4 bit 二进制能数到 16(0000∼1111),但 BCD 只用到 10 个编码(到 1001=9 就该进位了)。二进制加法的结果"多走了"被跳过的 6 个非法编码(1010∼1111),加 6 正好把这段落差补回来,让进位时序重新和十进制对齐。
格雷码(Gray Code)
格雷码的特点:相邻两个码字之间只有一位不同(only a single bit change from one code word to the next in sequence)。4 位格雷码序列:0000,0001,0011,0010,0110,0111,0101,0100,1100,1101,1111,1110,1010,1011,1001,1000。
二进制 ↔ 格雷码转换(EXAMPLE,从 MSB 开始逐位处理):
- 二进制 → 格雷码:最高位照抄;之后每一位格雷码 = 当前二进制位与前一位二进制位的异或(XOR)。例:110001102 → 最高位 1 照抄,后面逐位与左边一位比较:得到格雷码 10100101。
- 格雷码 → 二进制:最高位照抄;之后每一位二进制 = 当前格雷码位与前一位已算出的二进制位做异或(要带着已解码的结果继续往下走,而不是和上一位格雷码比较)。例:10101111 → 二进制 11000101。
为什么格雷码有优势? 课件用四相符号传输(QPSK 式的星座图)举例:发射端发送四个符号之一,符号在信道中被噪声干扰,接收端要把失真的符号解码回来;符号检测出错的概率与符号间距离成反比。用普通二进制编码 00,01,10,11 时,相邻编码可能同时有两位不同(如 01→10);一旦噪声让接收端误判到"中间状态",可能错成完全不同的值。而格雷码相邻码字只差一位,即使判错也只会错到"最接近的那个值",把误差限制在最小范围。另一个直观例子:011→100 在二进制下要翻转全部三位,中间可能短暂出现 010,001,101,110,111 等错误状态;格雷码下相邻变化永远只翻一位,不存在这种中间态风险。这也正是格雷码被用于旋转编码器(encoder)等物理场景的原因——多位同时翻转的瞬间不一致问题被彻底消除。
字母数字编码(Alphanumeric Codes):ASCII
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)用二进制编码英文字母、数字和符号,是字符在计算机中存储的基础。
检错码(Error Codes)
数据在传输或存储中可能出错(某位 0 变 1 或反之)。两种检错方案:
奇偶校验位(Parity Bit)
给一组数据位附加一个校验位,使整组中 1 的个数恒为偶数(even parity)或恒为奇数(odd parity)。接收端数一下 1 的个数,不符合约定即判为出错。
课件例题:奇校验(odd parity)系统收到以下码组:10110、11010、110011、110101110100、1100010101010,哪些出错?数每组 1 的个数:10110 有 3 个(合法)、11010 有 3 个(合法)、110011 有 4 个(偶数个,出错)、110101110100 有 7 个(合法)、1100010101010 有 6 个(偶数个,出错)。所以出错的两组是 110011 和 1100010101010。
局限:奇偶校验只能检测奇数个位同时出错的情况(1 个、3 个……),两位同时出错就漏检了,而且它只能"检测"不能"纠正"——不知道错在哪一位。
循环冗余校验(Cyclic Redundancy Check, CRC)
CRC 是能检测数据块中多个错误的检错方法:
- 发送端:对数据块计算出一个校验和(checksum),附在数据后面一起发送;
- 接收端:用同样的方法重新计算校验和并比对,结果为零说明未检出差错,非零说明出错。
计算过程基于模 2 运算(modulo-2 operation,即 XOR 异或)的多项式除法(EXAMPLE):
- 数据 D=11010011,生成码(generator code)G=1010(4 位,意味着后面要补 4−1=3……按课件记法补 4 个 0:D′=110100110000);
- 用 D′ 对 G 做模 2 除法(XOR 除法,不借位不进位),得余数(remainder)即校验和 0100;
- 发送的 CRC 码 = 原数据 + 校验和 = 110100110100。
接收端收到后:如果传输中某一位出错,再去做同样的模 2 除法会得到非零余数——错误被检测出来。
自测:True/False Quiz(课件第 73 页,附答案与解析)
- 八进制是加权系统,有八个数字。True(数字 0–7,权重 8x)。
- 二进制是加权系统,有两个数字。True。
- MSB 指 most significant bit。True。
- 十六进制里 9+1=10。False——十六进制里 9+1=A(A 才对应十进制的 10;写成 "10" 的十六进制数代表 16)。
- 二进制数 1111 的补码(2's complement)是 0000。False——取反得 0000,再加 1 得 0001。
- 有符号二进制数最右边那位是符号位。False——符号位在最左边(MSB)。
- 十六进制有 16 个字符,其中 6 个是字母。True(A–F)。
- BCD 指 binary coded decimal。True。
- 通过验证奇偶校验位可以检测给定编码中的错误。True(仅限奇数个位错误的情况)。
- CRC 指 cyclic redundancy check。True。
本章核心公式与结论速查
| 内容 | 结论 |
|---|---|
| Base-R 通式 | (N)R=∑ai×Ri |
| N 位无符号范围 | [0,2N−1] |
| N 位原码范围 | [−(2N−1−1),2N−1−1],0 有两种表示,加法不工作 |
| N 位补码范围 | [−2N−1,2N−1−1],取负 = 取反加一 |
| 二进制加法 | 1+1=10,进位 1;补码加法最高位进位直接丢弃 |
| 补码加减溢出判断 | 同号相加得异号结果 ⇒ 溢出 |
| IEEE 754 单精度 | 1 sign + 8 biased exponent (bias=127) + 23 fraction,隐含前导 1 |
| 特殊值 | exp 全 0 & frac 全 0 = ±0;exp 全 1 & frac 0 = ±∞;exp 全 1 & frac≠0 = NaN |
| BCD 加法 | 二进制相加后,4 位组 >9 则加 0110 |
| 格雷码 | 相邻码字仅 1 位不同;转换用 XOR,从 MSB 开始 |
| 奇偶校验 | 1 的个数奇偶性被破坏 ⇒ 检出错误 |
| CRC | 模 2(XOR)除法取余数作校验和,接收端余数非零 ⇒ 出错 |