题2.3.5

题目

【2017 统考真题】已知 ,计算 f(n) 的 C 语言函数 f1 如下:

int f1(unsigned n) { 
    int sum=1, power=1;
    for (unsigned i=0; i<=n-1; i++) { 
        power*=2;
        sum+=power;
    }
    return sum;
}

将 f1 中的 int 都改为 float,可得到计算 f(n) 的另一个函数 f2。假设 unsigned 和 int 型数据都占 32 位,float 采用 IEEE754 单精度标准。请回答下列问题。

(1) 当 n=0 时,f1 会出现死循环,为什么?若将 f1 中的变量 i 和 n 都定义为 int 型,则 f1 是否还会出现死循环?为什么?

(2) f1(23) 和 f2(23) 的返回值是否相等?机器数各是什么(用十六进制表示)?

(3) f1(24) 和 f2(24) 的返回值分别为 33554431 和 33554432.0,为什么不相等?

(4) f(31)= ,而 f1(31) 的返回值却为 - 1,为什么?若使 f1(n) 的返回值与 f(n) 相等,则最大的 n 是多少?

(5) f2(127) 的机器数为 7F80 0000H,对应的值是什么?若使 f2(n) 的结果不溢出,则最大的 n 是多少?若使 f2(n) 的结果精确(无舍入),则最大的 n 是多少?

分析

  1. 由于 是 unsigned 型,因此 “ ” 是无符号数比较, 时, 的机器数为全 1, 值是 ,为 unsigned 型可表示的最大数,条件 “ ” 永真,因此出现死循环。 若 改为 型,则不会出现死循环。

因为 “ ” 是有符号整数比较,当 时, 的值是 -1,当 时,条件 “ ” 不成立,此时退出 for 循环。

  1. 的返回值相等。 ,其二进制形式是 24 个 1 。int 型数占 32 位, 没有溢出。float 型数有 1 个符号位, 8 个指数位, 23 个底数位, 23 个底数位可以表示 24 位的底数, 所以两者返回值相等。

的机器数是 FFFFH, 的机器数是 FFH。 是 0,指数位为 ,底数位是 舍入后数值增大,所以 大 1。

  1. 显然 已超出了 int 型数的表示范围,用 实现时得到的机器数为 32 个 1,作为 int 型解释时其值为 -1,即 的返回值为 -1 。

因为 int 型最大可表示的数是 0 后面加 31 个 1,因此使 的返回值与 相等的最大 值是 30 。

  1. IEEE 754 标准使用 “阶码全 1、尾数全 0 ” 表示无穷大。f2 的返回值为 float 型, 机器数 对应的值是 。当 时, ,对应的阶码为 ,尾数部分舍入后阶码加 1,最终阶码为 254,是 IEEE 754 单精度格式表示的最大阶码。因此使 结果不溢出的最大 值为 126 。

时, 为 24 位 1,float 型数有 24 位有效位,所以不需要舍入,结果精确。 因此使 获得精确结果的最大 值为 23 。

题43