数据的表示与运算:数制编码、整数运算、浮点数标准与大小端存储。
2.1 数制与编码
2.1.1 信息的二进制编码
计算机内部所有信息均采用二进制编码,原因如下:
- 二进制只有两种基本状态,易于用物理器件实现(高低电平、脉冲有无等)。
- 二进制编码和运算规则简单,便于电路实现。
- 两个符号0和1正好与逻辑值“假”和“真”对应,便于实现逻辑运算。
在计算机内部,数值数据的表示有两种:
- 直接用二进制数表示
- 采用二进制编码的十进制数(BCD码)
2.1.2 进位计数制
基本概念
- R进制:使用R个基本符号,遵循“逢R进一”规则,第i位的位权为$R^i$。
- 常用进制:
- 二进制(B):0,1
- 八进制(O):0~7
- 十进制(D):0~9
- 十六进制(H):0
9,AF
进制转换
- R进制 → 十进制:按权展开求和。
- 十进制 → R进制:整数部分除R取余,小数部分乘R取整。
- 二、八、十六进制互转:二进制三位一组得八进制,四位一组得十六进制;反之亦然。
2.1.3 定点数的编码表示
真值与机器数
- 真值:带正负号的数(如+1011, -1101)。
- 机器数:符号数字化的编码(0正1负)。
定点表示
- 定点小数:小数点固定在数的最左边,用于表示浮点数的尾数。
- 定点整数:小数点固定在数的最右边,用于表示整数。
原码
定义:最高位为符号位,其余位为数值的绝对值。
正数:
$$
[x]{\text{原}} = 0X{n-1}\dots X_0
$$负数:
$$
[x]{\text{原}} = 1X{n-1}\dots X_0
$$
表示范围(n位):
$$
[-(2^{n-1}-1),\ 2^{n-1}-1]
$$
0有两种表示(+0和-0)。优点:直观,与真值转换简单。
缺点:加减运算复杂。
补码
定义:
正数:
$$
[x]{\text{补}} = [x]{\text{原}}
$$负数:
$$
[x]_{\text{补}} = 2^n + x
$$
(即原码取反加1)
表示范围(n位):$
$$
[-2^{n-1},\ 2^{n-1}-1]
$$
0的表示唯一。特殊值(n位):
$$
[-1]_{\text{补}} = 1,11\ldots 11
$$(n个1)
$$
[2^{n-1}-1]_{\text{补}} = 0,11\ldots 11
$$(n-1个1)
$$
[-2^{n-1}]_{\text{补}} = 1,00\ldots 00
$$(n-1个0)
原码 ↔ 补码快速转换:从低位向高位找到第一个1,该位及更低位的所有位不变,更高位全部取反(符号位也取反)。
反码
- 负数的反码 = 原码符号位不变,数值位取反。
移码(阶码)
定义:
$$
[x]_{\text{移}} = 2^{n-1} + x
$$
(n位),相当于真值加偏置值
$$
2^{n-1}
$$表示范围:与补码相同,
$$
[-2^{n-1},\ 2^{n-1}-1]
$$特殊值(n位):
$$
[-2^{n-1}]_{\text{移}} = 00\ldots 00
$$$$
[0]_{\text{移}} = 10\ldots 00
$$
(唯一)
习题(选择题)
对真值0表示形式唯一的编码方式是(B. 补码和移码)
108对应的十六进制形式是(A. 6CH)
下列数中最小的数是(计算比较)
由
$$
[X]{\text{原}}求[-X]{\text{原}}
$$
的做法是(B. 符号位取反,其他各位不变)由
$$
[X]{\text{补}}求[-X]{\text{补}}
$$
的做法是(D. 连同符号位一起取反,末位+1)关于补码和移码关系的叙述错误的是(B. 0的补码和移码表示相同)
给定$X=-01001010B$,机器数10110110B,判断编码方式(C. 补码)
8位补码,-26的机器数为(C. E6H)
9BH对应的十进制数为(C. -101)
2.2 整数的表示
2.2.1 无符号整数的表示
所有位均表示数值,没有符号位。
n位表示范围:
$$
[0,\ 2^n-1]
$$
2.2.2 带符号整数的表示
- 现代计算机采用补码表示带符号整数,原因:
- 0的表示唯一。
- 加减运算统一为加法,符号位与数值位一起运算。
- 可多表示一个最小负数。
2.2.3 零扩展与符号扩展
- 零扩展:高位补0(适用于无符号数)。
- 符号扩展:高位补符号位(适用于有符号数补码表示)。
- 正数补0,负数补1。
2.2.4 C语言中的整数类型
基本类型(32位环境)
| 类型 | 位数 | 默认 | 范围 |
|---|---|---|---|
| char | 8 | 无符号 | 0~255 |
| short | 16 | 有符号 | $-2^{15}\sim 2^{15}-1$ |
| int | 32 | 有符号 | $-2^{31}\sim 2^{31}-1$ |
| unsigned 前缀 | 同长度 | 无符号 | 相应范围 |
类型转换
- 同长度转换(如有符号↔无符号):不改变机器数,只改变解释方式。
- 不同长度转换:
- 低→高:有符号数进行符号扩展,无符号数进行零扩展。
- 高→低:直接截断高位。
习题
- -1029的16位补码十六进制为(D. FBFBH)
- short si=-8196; unsigned short usi=si; 则usi的值为(D. 57340)
- X=-1011的8位补码为(C. 11110101)
- 8位补码$[x]{\text{补}}$,求$[-x]{\text{补}}$时会发生溢出的为(C. 10000000)
- 8位移码$[x]{\text{移}}$,求$[-x]{\text{移}}$时会发生溢出的为(A. 11111111)
- 通常表示主存地址的是(D. 无符号数)
- unsigned short x=65530; unsigned int y=x; y的机器数为(B. 0000 FFFAH)
- 由3个“1”和5个“0”组成的二进制补码,能表示的最小整数是(A. -126)
- short si=-32767; unsigned short usi=si; usi的值为(D. 32769)
- 冯·诺依曼结构计算机数据采用二进制编码的原因(D. I、II和III)
- unsigned short usi=65535; short si=usi; si的值为(A. -1)
2.3 运算方法和运算电路
2.3.1 定点数的移位运算
逻辑移位
- 将操作数视为无符号数。
- 左移:高位丢弃,低位补0;若移出1则溢出。
- 右移:低位丢弃,高位补0。
算术移位
- 将操作数视为有符号数(补码)。
- 左移:高位丢弃,低位补0;若移位前后符号位不同则溢出。
- 右移:低位丢弃,高位补符号位。
2.3.2 定点数的运算
2.3.2.1 补码加减运算
运算公式
- $[x+y]{\text{补}} = [x]{\text{补}} + [y]_{\text{补}} \mod 2^n$
- $[x-y]{\text{补}} = [x]{\text{补}} + [-y]_{\text{补}} \mod 2^n$
- 求$[-y]{\text{补}}$:将$[y]{\text{补}}$各位取反,末位加1。
加减运算部件
- 输入:$X$、$Y$(n位补码),$Sub$(1位,0加1减)。
- 通过多路选择器,当$Sub=0$时,直接传$Y$,进位$Cin=0$;当$Sub=1$时,传$Y$的反码,$Cin=1$。
- 输出:和$F$,以及四个标志位。
标志位
- OF(溢出标志):$OF = C_n \oplus C_{n-1}$(最高位进位与次高位进位异或)。
- SF(符号标志):$SF = F_n$(结果的最高位)。
- CF(进位/借位标志):$CF = C_{in} \oplus C_{out}$(对无符号数有意义)。
- ZF(零标志):$ZF = (F == 0)$。
溢出判断
- 一位符号位法:$V = X_s Y_s \overline{F_s} + \overline{X_s},\overline{Y_s} F_s$
- 进位法:$V = C_n \oplus C_{n-1}$
- 双符号位法:用两位符号位,$00$正无溢出,$01$正溢出,$10$负溢出,$11$负无溢出;$V = S_{s1} \oplus S_{s2}$。
比较大小
- 无符号数:
- $ZF=1$ → $A=B$
- $ZF=0, CF=0$ → $A>B$
- $ZF=0, CF=1$ → $A<B$
- 有符号数:
- $ZF=1$ → $A=B$
- $ZF=0, OF \oplus SF = 0$ → $A>B$
- $ZF=0, OF \oplus SF = 1$ → $A<B$
2.3.2.2 定点数的乘法运算(原码)
基本原理
- 符号位:两乘数符号位异或。
- 数值部分:两绝对值相乘(无符号数乘法)。
计算机实现(迭代算法)
- 初始化:部分积$P_0=0$,乘数$Y$,被乘数$X$(绝对值)。
- 重复n次:
- 若$Y$的最低位为1,则$P_{i+1} = (P_i + X) >> 1$(右移一位);
- 若$Y$的最低位为0,则$P_{i+1} = P_i >> 1$;
- $Y$同步右移,移出的位丢弃。
- 最终$P$为乘积的高n位,$Y$为低n位。
溢出判断
- 有符号数:乘积高n位全相同且等于低n位的符号位,则未溢出。
- 无符号数:乘积高n位全0,则未溢出。
习题(2.3部分)
- 8位无符号数10010101右移一位得(A. 0100 1010)
- 8位补码10010101右移一位得(D. 1100 1010)
- 8位补码10010101扩展为16位十六进制(C. FF95H)
- ALU核心部件是(C. 加法器)
- x=69,y=38,加法器输入及进位(A. 01000101、00100110、0)
- x-y运算,输入及进位(D. 01000101、11011010、1)
- x=-69,y=-38,x+y输入及进位(A. 10111011、11011010、0)
- x=-69,y=-38,x-y输入及进位(C. 10111011、00100101、1)
- x=63,y=-31,x+y机器数及OF(B. 20H、0)
- [x]=F5H,[y]=7EH,x+y及OF(A. 115、0)
- 7E5H+4D3H=(C. CB8H)
- 移位运算说法正确的(D. I、II、III)
- x=127,y=-9,z=x+y结果(D. x=0000007FH, y=FFF7H, z=00000076H)
- 8位补码乘法溢出判断(B. r2×r3)
- [x]=11110100,[y]=10110000,z=2x+y/2机器数为(D. 溢出)
- x=103,y=-25,补码运算溢出的是(C. x-y)
- x=FFFFFFDFH,y=00000041H,x-y机器数(C. x=-33,y=65,机器数为FFFF FF9EH)
- 11011000逻辑右移1位和算术右移1位得(B. 01101100、11101100)
- x=FFFFFFFFH,y=FFFFFFF0H,x-y的CF和OF(A. CF=0, OF=0)
2.4 浮点数的表示和运算
2.4.1 浮点数的表示
表示格式
任意实数$X = (-1)^S \times M \times R^E$
- $S$:符号位(0正1负)
- $M$:尾数(定点小数,通常用原码)
- $E$:阶码(定点整数,通常用移码)
- $R$:基数(通常为2)
浮点数格式由$S$、$E$、$M$的位数和编码方式决定。
阶码位数决定表示范围,尾数位数决定精度。
表示范围
- 数轴对称,有上溢区、下溢区。
- 机器零:尾数为0时,通常将阶码也置0来唯一表示0。
规格化
- 目的:使尾数最高位不为0,尽可能保留有效数字。
- 左规:尾数最高位为0时,尾数左移,阶码减1(可多次)。
- 右规:尾数有效位进到小数点前时,尾数右移,阶码加1(最多一次)。
2.4.1.3 IEEE754标准
基本格式
- 单精度(float):1位符号 + 8位阶码 + 23位尾数,偏置值127。
- 双精度(double):1位符号 + 11位阶码 + 52位尾数,偏置值1023。
尾数隐藏位
- 规格化浮点数尾数最高位恒为1,IEEE754将其隐藏,因此实际尾数有效位为1.f(f为23/52位小数部分)。
- 真值:$(-1)^s \times 1.f \times 2^{e - \text{bias}}$。
阶码范围
- 单精度:e=1~254(全0和全1有特殊含义)。
- 双精度:e=1~2046。
特殊值
| 情况 | 符号 | 阶码 | 尾数 | 值 |
|---|---|---|---|---|
| +0 | 0 | 0 | 0 | 0 |
| -0 | 1 | 0 | 0 | -0 |
| +∞ | 0 | 全1 | 0 | +∞ |
| -∞ | 1 | 全1 | 0 | -∞ |
| NaN | 0/1 | 全1 | ≠0 | NaN(非数) |
| 非规格化数 | 0/1 | 0 | ≠0 | $\pm 2^{-126}\times 0.f$(单精度) |
示例
- 将-0.75转换为IEEE754单精度:$(-0.75)_{10} = (-0.11)_2 = -1.1\times 2^{-1}$,则$s=1$,$e=127-1=126=01111110_2$,$f=1000…0$,结果为$1\ 01111110\ 1000…0$,即BF400000H。
- 求COA00000H的值:二进制$1\ 10000001\ 0100000…0$,$e=129$,$E=129-127=2$,$f=0.01_2$,$1.f=1.01_2=1.25$,真值$=-1.25\times 2^2=-5$。
2.4.2 浮点数的加减运算
步骤
- 对阶:小阶向大阶看齐,尾数右移,阶码增加,右移位数=阶差。
- 尾数加减:隐藏位、保留位一起参与运算。
- 规格化:
- 若尾数出现进位到整数位(如$1.b… + 1.b… = 1b…$),则右规一次。
- 若尾数出现$0.0…01b…$,则左规直到最高位为1。
- 舍入:对阶或右规时移出的低位保留,运算后按规则舍入(0舍1入、恒置1、截断)。
- 溢出判断:阶码超出范围则溢出(上溢置无穷,下溢置0)。
注意
- 右规前需检查阶码是否已为全1,避免上溢。
- 左规前需检查阶码是否已为全0,避免下溢。
2.4.3 C语言中的浮点数类型
- float ↔ double:转换可能引起精度变化。
- int → float:范围可能增大,精度可能下降(24位有效数字 vs 31位)。
- float → int:截断小数部分,可能溢出。
2.4.4 数据的大小端存储
- 大端:低地址存高位字节(MSB)。
- 小端:低地址存低位字节(LSB)。
例:32位整数01234567H存储:
- 大端:地址递增存放01,23,45,67
- 小端:地址递增存放67,45,23,01
习题(2.4部分)
- IEEE754单精度41A4C000H对应十进制(20.59375)
- x=-8.25的IEEE754单精度表示为(C104 0000H)
- float能表示的最大正整数是($2^{127}-2^{103}$)
- C6400000H对应的数值($-1.5\times 2^{13}$)
- (f1)=CC900000H, (f2)=B0C00000H,x和y关系(x<y且符号相同)
- 小端方式,double型1122334455667788H存放在0000 8040H开始,8046H存放(77H)
- IEEE754单精度最小规格化正数是($1.0\times 2^{-126}$)
- 小端方式,int i=0对应C745FC00000000,则int i=-64对应(C745FCFFFFC0)
- 机器数为C8000000H,可能的值($-7\times 2^{27}$)