强化阶段笔记
1. 定点整数运算
1.1. 16 进制补码和 10 进制
- 如果前导
F比较多,利用0x(FFFF...F) = -1,用-1减去二进制就可以消去所有F,然后列方程解出十进制。 - 二级结论:
0xFFFX -> X - 16,0XFFXY -> 16X + Y - 256。
2. 浮点数
2.1. 加减法舍入操作
- 发生在对阶、尾数加减、规格化的所有操作最后。
- 在这之前,左右规产生的补位都保留(即使超过有效位数)。
- 舍入时,丢弃尾数最后一段超出长度的部分,同时,若丢弃的部分最高位为 1,则丢完后尾数末尾 +1,否则不变。
- 注意:判断要不要加 1 单独在舍入阶段进行,和左右规无关!
2.2. IEEE754 单精度加减法
- 结构:
F32 = 1 + 8 + 23,1 位尾数符号,8 位移码阶码,23 位原码尾数(省略最高位 1,实际尾数 24 位) - 省略的 1 是个位的,权重是 1 而不是
! - 注意事项
- 先对阶,对阶时就要还原尾数最高位省略的 1。
- 加减完要规格化。
- 最后还要记得把最高位 1 省掉。
- 减法一般不用补码算,手动判断哪个更大,先得符号,最后绝对值大减小的即可。
2.3. 精度问题
- 若两个浮点数
和 加减, 的阶码远大于 的阶码,则在对阶时, 可能因为右规超出尾数位数,导致尾数变为 0。 - 此时
或 结果都是 。产生误差。
- 此时
题目
- 有三个变量
int i,float f,double d。其中i = 785,f = 1.5678e3,d=1.5e100。设int用补码表示,float和double分别用 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 位,可以用单精度浮点数精确表示。所以相等。
- 换言之,若超过
,即超出 24 位尾数能表示的最大范围,就会出现误差。 - 对于
虽然需要 25 位二进制,但是除最高位外全 0。因此可用 表示,尾数全 0,阶码 。 - 若整数超过
,则至少需要 25 位二进制来表示,且除最高位外不为全 0,因此尾数部分会舍入,导致误差。
- 换言之,若超过
- 对于 3,要注意到 d 和 f 的阶码(数量级)差异巨大。在对阶时,f 尾数会右移过多导致舍入为 0。因此
(d + f) - d实际上应得机器 0。所以不等。 - 拓展:对于超出
的整数,并非都不能被精确表示,而是能被精确表示的数字间隔已经大于了 1(浮点数的步长) - 例如,在
范围内的整数,需要 25 位二进制表示。 - 由于 24 位尾数,会有 1 位最低位被丢弃。若最低位本来就是 0,则不会产生误差。
- 因此,能被精确表示的整数最低位都是 0,即偶数。
- 同理可推得
区间内的整数,仅当最低两位为 0 时才能避免舍入误差。即 4 的倍数。以此类推直到阶码溢出。
- 例如,在
- 总结:在 IEEE754 表示下,设尾数位数为
(不算最高位),则一个数 能被精确表示 表示为二进制科学计数法 后,有效小数部分 不得超过 位,且 不超过阶码表示范围。 - 对于单精度
,双精度 。 无论是整数 or 小数都适用。
- 对于 1,785 的二进制位数不超过 24 位,可以用单精度浮点数精确表示。所以相等。
- 有三个变量