浮点数的加减乘除。

# Lecture05 - 浮点数运算

# 回顾

记忆 1+8+23 的(符号位移码原码)

记忆各种情况对应的表示

image-20221013162002689

# 加法和减法

image-20221013162704448

  1. 检查 0:如果有 0 存在可以不用计算

  2. 对齐有效位:阶码向大值对齐,因为右移较小的数而丢失的数字所造成的的影响较小。右移较小的数有效值的幅值部分 1 位,并将阶值加 1。如果两个数的阶值差别非常大,则较小的数丢失

  3. 加或减有效值:原码加减法

  4. 规格化结果:把结果调整为左移有效值直到最高有效数字为非 0

    (右规最多是两位,最多是 1.1111...+1.xxxx,对应有效值的上溢)

# 溢出

image-20221013164459041

  1. 阶值上溢

​ 最大允许阶值 127(11111110)

​ 右移可能会导致阶值的上溢

  1. 阶值下溢

    最小阶值为 - 126(00000001)

    左移可能会引起阶值的下溢

  2. 有效值的上下溢只存在于右规

    image-20221013171503186

# 异常

image-20221014093204887

关于数太小阶下溢的问题,在 cpp 中,如果是单精度浮点数,会用非规格化数表示,如果是双精度浮点数,会直接用 0 表示。

# 原码的加法

image-20221013165531300

image-20221013165721396

求补的时候加了 2 的 n 次方

有进位说明 a>b

无进位说明 a<b

image-20221014103516514

image-20221013172902710

01111110 ——127 23 表示有 23 个零

01111101 ——126 21 表示有 21 个零

差了一位,左移一位

image-20221013173317582

1111110 127

1111101 126

然后给 0.4375 取个反

# 乘法和除法

image-20221013163420919

注意乘法和除法的阶值计算 ——

  • 乘法加 bias
  • 除法减 bias
  • bias 的值为 127【通常,移码的偏移量为 2k-1 -1,移码的偏移量主要是看想表示多少个负数和多少个正数,阶码的范围是 - 126~127,-127 和 128 分别表示特殊的数】

# 乘法

image-20221013173727304

对于乘法来说,只有右规。【1.x * 1.x 只可能超出】

image-20221013173847536

image-20221013174221322

最高两位为 01,不用处理。

# 除法

image-20221013174335704

x 和 y 可能都是 0,可能会报错或者是正负无穷

对于除法来说,只有左规。【1.x/ 1.x 】

image-20221013174656673

# 精度保护

image-20221013174820265

y 需要左移一位对齐,所以最后一位 1 在不使用附加位的情况下会丢失。

image-20221013175053246

一般而言,多余位的值超过了最低可表示位值的一半,则进位。

重点关注 “10” 强制结果为偶数的分类讨论。如果结果的最低可表示位是 1,结果向上入;当最低可表示位是 0,结果向下入。

image-20221013175347832

朝 0 摄入,被截断值的幅值总是小于或等于更精确原值的幅值,在计算中产生一致的向下偏差。

# 精度考虑

image-20221014105545840

x == (int)(float) x

int 型有 32 位,但是 float 精度只能保存 24 位,会有精度的损失。

x * x >= 0 否

(D + F) - D == F 什么时候不成立?

右边计算出来为 double 型,左边是 float

float f = 1.0f;
for(int i = -100; i < 100; i++){
    double d = pow(2,i);
    if((d + f - d) == f){
        cout << i << endl;
    }
}

对于此例情况,当 i 大于 53 或等于 - 53 时,会输出。

因为此时 f 相对于 d 较小,相当于 0。

补充:双精度 64(1+11+52)小数部分有 52 位。别的情况,i 会有不同的值对应。

  1. i 大于 53 的情况

    image-20221018190250710

    舍入位虽然是 10,但前置位已经是 0(偶数),因此不进位,所以有精度的丢失。

  2. i 等于 - 53 的情况

image-20221018190243583

​ 舍入位是 10,前置位是 1,因此要进位,从而造成了误差。

只要有精度的丢失,就是 “否”