数据的表示与运算:数制编码、整数运算、浮点数标准与大小端存储。

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):09,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
      $$
      (唯一)

习题(选择题)

  1. 对真值0表示形式唯一的编码方式是(B. 补码和移码)

  2. 108对应的十六进制形式是(A. 6CH)

  3. 下列数中最小的数是(计算比较)


  4. $$
    [X]{\text{原}}求[-X]{\text{原}}
    $$
    的做法是(B. 符号位取反,其他各位不变)


  5. $$
    [X]{\text{补}}求[-X]{\text{补}}
    $$
    的做法是(D. 连同符号位一起取反,末位+1)

  6. 关于补码和移码关系的叙述错误的是(B. 0的补码和移码表示相同)

  7. 给定$X=-01001010B$,机器数10110110B,判断编码方式(C. 补码)

  8. 8位补码,-26的机器数为(C. E6H)

  9. 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 前缀 同长度 无符号 相应范围

类型转换

  • 同长度转换(如有符号↔无符号):不改变机器数,只改变解释方式。
  • 不同长度转换
    • 低→高:有符号数进行符号扩展,无符号数进行零扩展。
    • 高→低:直接截断高位。

习题

  1. -1029的16位补码十六进制为(D. FBFBH)
  2. short si=-8196; unsigned short usi=si; 则usi的值为(D. 57340)
  3. X=-1011的8位补码为(C. 11110101)
  4. 8位补码$[x]{\text{补}}$,求$[-x]{\text{补}}$时会发生溢出的为(C. 10000000)
  5. 8位移码$[x]{\text{移}}$,求$[-x]{\text{移}}$时会发生溢出的为(A. 11111111)
  6. 通常表示主存地址的是(D. 无符号数)
  7. unsigned short x=65530; unsigned int y=x; y的机器数为(B. 0000 FFFAH)
  8. 由3个“1”和5个“0”组成的二进制补码,能表示的最小整数是(A. -126)
  9. short si=-32767; unsigned short usi=si; usi的值为(D. 32769)
  10. 冯·诺依曼结构计算机数据采用二进制编码的原因(D. I、II和III)
  11. 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部分)

  1. 8位无符号数10010101右移一位得(A. 0100 1010)
  2. 8位补码10010101右移一位得(D. 1100 1010)
  3. 8位补码10010101扩展为16位十六进制(C. FF95H)
  4. ALU核心部件是(C. 加法器)
  5. x=69,y=38,加法器输入及进位(A. 01000101、00100110、0)
  6. x-y运算,输入及进位(D. 01000101、11011010、1)
  7. x=-69,y=-38,x+y输入及进位(A. 10111011、11011010、0)
  8. x=-69,y=-38,x-y输入及进位(C. 10111011、00100101、1)
  9. x=63,y=-31,x+y机器数及OF(B. 20H、0)
  10. [x]=F5H,[y]=7EH,x+y及OF(A. 115、0)
  11. 7E5H+4D3H=(C. CB8H)
  12. 移位运算说法正确的(D. I、II、III)
  13. x=127,y=-9,z=x+y结果(D. x=0000007FH, y=FFF7H, z=00000076H)
  14. 8位补码乘法溢出判断(B. r2×r3)
  15. [x]=11110100,[y]=10110000,z=2x+y/2机器数为(D. 溢出)
  16. x=103,y=-25,补码运算溢出的是(C. x-y)
  17. x=FFFFFFDFH,y=00000041H,x-y机器数(C. x=-33,y=65,机器数为FFFF FF9EH)
  18. 11011000逻辑右移1位和算术右移1位得(B. 01101100、11101100)
  19. 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. 对阶:小阶向大阶看齐,尾数右移,阶码增加,右移位数=阶差。
  2. 尾数加减:隐藏位、保留位一起参与运算。
  3. 规格化
    • 若尾数出现进位到整数位(如$1.b… + 1.b… = 1b…$),则右规一次。
    • 若尾数出现$0.0…01b…$,则左规直到最高位为1。
  4. 舍入:对阶或右规时移出的低位保留,运算后按规则舍入(0舍1入、恒置1、截断)。
  5. 溢出判断:阶码超出范围则溢出(上溢置无穷,下溢置0)。

注意

  • 右规前需检查阶码是否已为全1,避免上溢。
  • 左规前需检查阶码是否已为全0,避免下溢。

2.4.3 C语言中的浮点数类型

  • floatdouble:转换可能引起精度变化。
  • intfloat:范围可能增大,精度可能下降(24位有效数字 vs 31位)。
  • floatint:截断小数部分,可能溢出。

2.4.4 数据的大小端存储

  • 大端:低地址存高位字节(MSB)。
  • 小端:低地址存低位字节(LSB)。

例:32位整数01234567H存储:

  • 大端:地址递增存放01,23,45,67
  • 小端:地址递增存放67,45,23,01

习题(2.4部分)

  1. IEEE754单精度41A4C000H对应十进制(20.59375)
  2. x=-8.25的IEEE754单精度表示为(C104 0000H)
  3. float能表示的最大正整数是($2^{127}-2^{103}$)
  4. C6400000H对应的数值($-1.5\times 2^{13}$)
  5. (f1)=CC900000H, (f2)=B0C00000H,x和y关系(x<y且符号相同)
  6. 小端方式,double型1122334455667788H存放在0000 8040H开始,8046H存放(77H)
  7. IEEE754单精度最小规格化正数是($1.0\times 2^{-126}$)
  8. 小端方式,int i=0对应C745FC00000000,则int i=-64对应(C745FCFFFFC0)
  9. 机器数为C8000000H,可能的值($-7\times 2^{27}$)