Skip to content

强化阶段笔记

1. 定点整数运算

1.1. 16 进制补码和 10 进制

  • 如果前导 F 比较多,利用 0x(FFFF...F) = -1 ,用 -1 减去二进制就可以消去所有 F,然后列方程解出十进制。
  • 二级结论:0xFFFX -> X - 160XFFXY -> 16X + Y - 256

2. 浮点数

2.1. 加减法舍入操作

  • 发生在对阶、尾数加减、规格化的所有操作最后。
  • 在这之前,左右规产生的补位都保留(即使超过有效位数)。
  • 舍入时,丢弃尾数最后一段超出长度的部分,同时,若丢弃的部分最高位为 1,则丢完后尾数末尾 +1,否则不变
  • 注意:判断要不要加 1 单独在舍入阶段进行,和左右规无关!

2.2. IEEE754 单精度加减法

  • 结构:F32 = 1 + 8 + 23,1 位尾数符号,8 位移码阶码,23 位原码尾数(省略最高位 1,实际尾数 24 位)
  • 省略的 1 是个位的,权重是 1 而不是 1/2
  • 注意事项
    • 先对阶,对阶时就要还原尾数最高位省略的 1。
    • 加减完要规格化。
    • 最后还要记得把最高位 1 省掉。
    • 减法一般不用补码算,手动判断哪个更大,先得符号,最后绝对值大减小的即可。

2.3. 精度问题

  • 若两个浮点数 AB 加减,A 的阶码远大于 B 的阶码,则在对阶时,B 可能因为右规超出尾数位数,导致尾数变为 0。
    • 此时 A+BAB 结果都是 A。产生误差。

题目

    1. 有三个变量 int ifloat fdouble d。其中 i = 785f = 1.5678e3d=1.5e100。设 int 用补码表示,floatdouble 分别用 IEEE754 单/双精度浮点数。在 32 位机器上执行下列判断式,结果为 true 的是()
    • (1)i == (int)(float) i
    • (2)f == (float)(int) f
    • (3)f == (float)(double) f
    • (4)(d + f) - d == f
    • A. 1,2;
    • B. 1,3;
    • C. 2,3;
    • D. 3,4;
    • 答案:B
    • 解析:2 和 3 很好判断。主要是判断 1 和 4 的对错。
      • 对于 1,785 的二进制位数不超过 24 位,可以用单精度浮点数精确表示。所以相等。
        • 换言之,若超过 224=16777216,即超出 24 位尾数能表示的最大范围,就会出现误差。
        • 对于 224 虽然需要 25 位二进制,但是除最高位外全 0。因此可用 1.0×224 表示,尾数全 0,阶码 j=24+127
        • 若整数超过 224,则至少需要 25 位二进制来表示,且除最高位外不为全 0,因此尾数部分会舍入,导致误差。
      • 对于 3,要注意到 d 和 f 的阶码(数量级)差异巨大。在对阶时,f 尾数会右移过多导致舍入为 0。因此 (d + f) - d 实际上应得机器 0。所以不等。
      • 拓展:对于超出 224 的整数,并非都不能被精确表示,而是能被精确表示的数字间隔已经大于了 1(浮点数的步长)
        • 例如,在 [224,225) 范围内的整数,需要 25 位二进制表示。
        • 由于 24 位尾数,会有 1 位最低位被丢弃。若最低位本来就是 0,则不会产生误差
        • 因此,能被精确表示的整数最低位都是 0,即偶数
        • 同理可推得 [225,226) 区间内的整数,仅当最低两位为 0 时才能避免舍入误差。即 4 的倍数。以此类推直到阶码溢出。
      • 总结:在 IEEE754 表示下,设尾数位数为 R(不算最高位),则一个数 N 能被精确表示
        • N 表示为二进制科学计数法 (1.M)2j 后,有效小数部分 M 不得超过 R,且 j 不超过阶码表示范围。
        • 对于单精度 R=23,双精度 R=52
        • N 无论是整数 or 小数都适用。