计算机组成原理——数据的表示与运算-浮点数的表示与运算(课程笔记)

说明

  1. 博客作为笔记备份,不定时更新
  2. 参考内容为《计算机组成原理(第3版)》唐朔飞 高等教育出版社;王道考研《计算机组成原理考研复习指导2023》
  3. 文中的例题摘自王道考研《计算机组成原理考研复习指导2023》,大多是我个人认为较为典型的题目以及错题的部分整理

文章目录

  • 浮点数的表示与运算
    • 1. 浮点数的表示
      • 1.1 浮点数的表示格式
      • 1.2 浮点数的表示范围
      • 1.3 浮点数的规格化
      • 1.4 IEEE 754 标准
        • IEEE 754 浮点数格式
        • IEEE 754 浮点数的范围
      • 1.5 定点表示 VS 浮点表示
    • 2. 浮点数的加减运算
      • 2.1 对阶
      • 2.2 尾数求和
      • 2.3 规格化
      • 2.4 舍入
      • 2.5 溢出判断
      • 2.6 C语言中的浮点数类型
        • int → \rightarrow float
        • int/float → \rightarrow double
        • double → \rightarrow float
        • float/double → \rightarrow int
    • 3. 例题
    • 更新文档

浮点数的表示与运算

1. 浮点数的表示

  • 浮点数表示法是指以适当的形式将比例因子表示在数据中,让小数点的位置根据需要而浮动,
  • 在位数有效的情况下,既扩大了数的表示范围,又保持了数的有效精度

1.1 浮点数的表示格式

  • 浮点数的表示形式
    N = ( − 1 ) S × M × R E N=(-1)^S\times M\times R^E N=(1)S×M×RE

    • S:浮点数的符号
    • M:一个二进制定点小数,称为尾数(mantissa),一般用定点原码小数表示
    • E:一个二进制定点整数,称为阶码指数,用移码表示
    • R:基数(隐含),可约定为2、4、16等
  • 32位浮点数格式举例

    • 第0位:数符
    • 第1~7位:用移码表示的阶码E(偏置值为64)
    • 第8~31位:24位二进制原码小数表示的尾数M
    • 基数R为2
    • 阶码的值反映浮点数的小数点的实际位置;阶码的位数反映浮点数的表示范围;尾数的位数反映浮点数的精度

1.2 浮点数的表示范围

  • 上溢
    • 正上溢:运算结果大于最大正数
    • 负上溢:运算结果小于绝对值最大负数
    • 数据一旦产生上溢,计算机必须中断运算操作,进行溢出处理
  • 下溢
    • 正下溢:运算结果在0和最小正数之间
    • 负下溢:运算结果在0和绝对值最小负数之间
    • 数据下溢时,浮点数值趋于0,计算机仅将其当做机器零处理

1.3 浮点数的规格化

  • 尾数的位数决定了浮点数的有效数位,有效数位越多,数据的精度越高。为了在浮点数运算过程中尽可能多的保留有效数字的位数,使有效数据尽量占满尾数数位,必须在运算过程中对浮点数进行规格化操作
  • 规格化:指通过调整一个非规格化浮点数的尾数和阶码的大小,使非零的浮点数尾数的最高数位上保证是一个有效值
    • 左规
      • 当运算结果的尾数的最高数位不是有效位,即出现 ± 0.00 ⋅ ⋅ ⋅ 0 × ⋅ ⋅ ⋅ × \pm 0.00···0\times··· \times ±0.00⋅⋅⋅0×⋅⋅⋅×的形式时,需要进行左规
      • 左规时,尾数每左移一位,阶码减一(基数为2时),直至尾数变成规格化形式
      • 左规可能要进行多次
    • 右规
      • 当运算结果的尾数的有效位进到小数点前面时,需进行右规
      • 右规时,将尾数右移一位,阶码加一(基数为2时)
      • 需要右规时,仅需进行一次
  • 原码表示的规格化尾数M的绝对值应满足 1 / R ≤ ∣ M ∣ ≤ 1 1/R\le |M|\le 1 1/RM1,若 R = 2 R=2 R=2,则有 1 / 2 ≤ ∣ M ∣ ≤ 1 1/2\le |M|\le 1 1/2M1
    • 正数为 0.1 × ⋅ ⋅ ⋅ × 0.1\times···\times 0.1×⋅⋅⋅×的形式,其最大值表示为 0.11 ⋅ ⋅ ⋅ 1 0.11···1 0.11⋅⋅⋅1,最小值表示为 0.100 ⋅ ⋅ ⋅ 0 0.100···0 0.100⋅⋅⋅0。尾数的表示范围为 1 / 2 ≤ M ≤ ( 1 − 2 − n ) 1/2\le M\le (1-2^{-n}) 1/2M(12n)
    • 负数为 1.1 × ⋅ ⋅ ⋅ × 1.1\times ···\times 1.1×⋅⋅⋅×的形式,其最大值表示为 1.10 ⋅ ⋅ ⋅ 0 1.10···0 1.10⋅⋅⋅0,最小值表示为 1.11 ⋅ ⋅ ⋅ 1 1.11···1 1.11⋅⋅⋅1。尾数的表示范围为 − ( 1 − 2 − n ) ≤ M ≤ − 1 / 2 -(1-2^{-n})\le M\le -1/2 (12n)M1/2
    • 基数不同,浮点数的规格化形式也不同。当浮点数尾数的基数为2时,原码规格化数的尾数最高位一定是1;当基数为4时,原码规格化形式的尾数最高两位不全为0

1.4 IEEE 754 标准

IEEE 754 浮点数格式

  • IEEE 754标准,浮点数的格式如下:
    • 若是32位单精度格式的浮点数,则数符占1位、阶码占8位、尾数占23位

    • 若是64位双精度格式的浮点数,则数符占1位、阶码占11位、尾数占52位

  • IEEE 754浮点数的格式
类型 数符 阶码 尾数数值 总位数 偏置值(十六进制和十进制)
短浮点数 1 8 23 32 7FH 127
长浮点数 1 11 52 64 3FFH 1023
临时浮点数 1 15 64 80 3FFFH 16383
  • IEEE 754标准的浮点数(除了临时浮点数外),其尾数用采取隐藏位侧率的原码表示,且阶码用移码表示的浮点数
    • 以短浮点数为例,最高位为数符位;其后是8位阶码,用移码表示,阶码的偏置值为 2 8 − 1 − 1 = 127 2^{8-1}-1=127 2811=127;基数为2;其后23位是原码表示的尾数数值位。在浮点格式中表示的23位尾数是纯小数。对于规格化的二进制浮点数,数值的最高位总是“1”,为了能使尾数多表示一位有效位,将这个“1”隐藏,称为隐藏位,因此23位尾数实际表示了24位有效数字。
    • 例如: ( 12 ) 10 = ( 1100 ) 2 (12)_{10}=(1100)_2 (12)10=(1100)2,将它规格化后结果为 1.1 × 2 3 1.1\times 2^3 1.1×23,其中整数部分的“1”将不存储在23位尾数内
    • 存储浮点数阶码之前,偏置值要先加到阶码真值上,例如上面的,阶码值为3,因此在短浮点数中,移码表示的阶码为 127 + 3 = 130 ( 82 H ) 127+3=130(82H) 127+3=130(82H);在长浮点数中,阶码为 1023 + 3 = 1026 = ( 402 H ) 1023+3=1026=(402H) 1023+3=1026=(402H)

IEEE 754 浮点数的范围

  • IEEE 754标准中,规格化的短浮点数的真值为 ( − 1 ) S × 1. M × 2 E − 127 (-1)^S\times 1.M\times 2^{E-127} (1)S×1.M×2E127;规格化长浮点数的真值为 ( − 1 ) S × 1. M × 2 E − 1023 (-1)^S\times 1.M\times 2^{E-1023} (1)S×1.M×2E1023。其中短浮点数的E的取值范围为 1254(8位表示),M为23位,共32位;长浮点数E的取值为12046(11位表示),M为52位,共64位
  • IEEE 754浮点数的范围
格式 最小值 最大值
单精度 E = 1 , M = 01.0 × 2 1 − 127 = 2 − 126 E=1,M=01.0\times2^{1-127}=2^{-126} E=1,M=01.0×21127=2126 E = 254 , M = . 111 ⋯   , 1.111 ⋯ 1 × 2 254 − 127 = 2 127 × ( 2 − 2 − 23 ) E=254,M=.111\cdots ,1.111\cdots 1\times 2^{254-127}=2^{127}\times(2-2^{-23}) E=254,M=.111,1.1111×2254127=2127×(2223)
双精度 E = 1 , M = 01.0 × 2 1 − 1023 = 2 − 1022 E=1,M=01.0\times 2^{1-1023}=2^{-1022} E=1,M=01.0×211023=21022 E = 2046 , M = . 1111 ⋯   , 1.111 ⋯ 1 × 2 2046 − 1023 = 2 1023 × ( 2 − 2 − 52 ) E=2046,M=.1111\cdots ,1.111\cdots 1\times2^{2046-1023}=2^{1023}\times(2-2^{-52}) E=2046,M=.1111,1.1111×220461023=21023×(2252)
  • 对于IEEE 754格式的浮点数,阶码全0或全1时,有其特别的解释
单精度 双精度
值的类型 符号 阶码 尾数 符号 阶码 尾数
正零 0 0 0 0 0 0 0 0
负零 1 0 0 -0 1 0 0 -0
正无穷大 0 255(全1) 0 ∞ \infty 0 2047(全1) 0 ∞ \infty
负无穷大 1 255(全1) 0 − ∞ -\infty 1 2047(全1) 0 − ∞ -\infty
  • 全0阶码全0尾数: + 0 / − 0 +0/-0 +0/0,零的符号取决于数符S,一般情况下+0和-0是等效的
  • 全1阶码全0尾数: + ∞ / − ∞ +\infty/-\infty +∞/ + ∞ +\infty +在数值上大于所有有限数, − ∞ -\infty 则小于所有有限数。引入无穷大的数的目的是,在计算过程出现异常的情况下使用程序能继续进行下去

1.5 定点表示 VS 浮点表示

比较内容 定点表示 浮点表示
数值的表示范围 字长相同时,浮点数的表示的数值范围远大于定点表示法
精度 字长相同时,定点数的精度较大 字长相同时,浮点数虽扩大了数的表示范围,但精度降低了
数的运算 较简单 较复杂
溢出问题 当运算结果超出数的表示范围时,溢出 运算结果超出尾数的表示范围不一定溢出,只有规格化后阶码超出所能表示的范围时,才发生溢出

2. 浮点数的加减运算

  • 浮点运算的特点是:阶码运算和尾数运算分开进行

2.1 对阶

  • 对阶的目的:使两个操作数的小数点位置对齐,即使得两个数的阶码相等
  • 先求阶差,然后以小阶向大阶看齐的原则,将阶码小的尾数右移一位(基数为2),阶加1,直至两个数的阶码相等为止
  • 尾数右移时,舍弃掉有效位会产生误差,影响精度

2.2 尾数求和

  • 将对阶后的尾数按定点数加/减运算规则运算
  • 运算后的尾数不一定是规格化的,需进一步进行规格化处理

2.3 规格化

  • 右规
    • 当结果为 ± 1 × . × ⋅ ⋅ ⋅ × \pm 1\times.\times···\times ±1×.×⋅⋅⋅×时,需进行右规,尾数右移一位,阶码加一
    • 尾数右移时,最高位1被移到小数点前一位作为隐藏位,最后一位移出时需考虑舍入
  • 左规
    • 当结果为 ± 0.0 ⋅ ⋅ ⋅ 01 × ⋅ ⋅ ⋅ × \pm0.0···01\times···\times ±0.0⋅⋅⋅01×⋅⋅⋅×时,需进行左规,尾数每左移一位,阶码减一
    • 可能需要进行多次左规,直到将第一位1移到小数点左边

2.4 舍入

  • 对阶和尾数右规时,可能会对尾数进行右移,为保证运算精度,一般将低位移出的两位保留下来,参与中间过程的运算,最后将运算结果进行舍入
  • 0舍1入法
    • 运算结果保留位的最高数位是0,舍去;最高数位是1,则在尾数末位加一
    • 这样可能会使尾数溢出,此时需再进行一次右规
  • 恒置1法
    • 只要因移位而丢失的位中有1,就把尾数末位置1
  • 截断法
    • 直接截取所需位数,丢弃后面的所有位

2.5 溢出判断

  • 右规和尾数舍入
    • 数值很大的尾数舍入时,可能因为末位加1而发生尾数溢出,此时需要通过右规来调整尾数和阶。右规时阶加1,导致阶增大,此时需判断是否发生了指数上溢
    • 例如:当调整前的阶码为 11111110 11111110 11111110时,加一后,会变成 11111111 11111111 11111111发生指数上溢
  • 左规
    • 左规时阶减一,导致阶减小,此时需判断是否发生了指数下溢
    • 左规一次阶码减一,判断阶码是否全为0来确定是否发生了指数下溢
  • 说明
    • 浮点数的溢出并非以尾数溢出来判断的,尾数溢出可以通过右规操作得到纠正
    • 运算结果是否溢出主要看结果的指数是否发生了上溢,因此是由指数上溢来判断的

2.6 C语言中的浮点数类型

int → \rightarrow float

  • 虽不会发生溢出,但float尾数连隐藏位共24位,当int型数据的第24~31(此处默认第0位为最高数位)位非0时,无法精确转换为24位浮点数的尾数,需进行舍入处理,影响精度

int/float → \rightarrow double

  • 因为double类型的有效位数更多,因此能保留精确值

double → \rightarrow float

  • 因float表示范围更小,因此大数转换时可能会发生溢出;此外,由于尾数有效位数变少,因此高精度数转换时会发生舍入

float/double → \rightarrow int

  • 因为int没有小数部分,因此数据会向0方向截断(仅保留整数部分),发生舍入。此外,因为int表示范围更小,因此大数转换时可能会溢出

3. 例题

更新文档

更新日期 更新内容

你可能感兴趣的:(课程笔记,算法,浮点数的表示与运算)