2017-43
已知 f(n)=∑i=0n2i=2n+1-1=(11…1)2,计算 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 采用 IEEE 754 单精度标准。请回答下列问题。
(1)当 n=0 时,f1 会出现死循环,为什么?若将 f1 中的变量 i 和 n 都定义为 int 型,则 f1 是否还会出现死循环?为什么?
(2)f1(23)和 f2(23)的返回值是否相等?机器数各是什么(用十六进制表示)?
(3)f1(24)和 f2(24)的返回值分别为 33 554 431 和 33 554 432.0,为什么不相等?
(4)f(31)=232-1,而 f1(31) 的返回值却为 -1,为什么?若使 f1(n) 的返回值与 f(n) 相等,则最大的 n 是多少?
(5)f2(127)的机器数为 7F80 0000H,对应的值是什么?若使 f2(n)的结果不溢出,则最大的 n 是多少?若使 f2(n)的结果精确(无舍入),则最大的 n 是多少?
(1)当 n=0 时,i 和 n 均为 unsigned 型,表达式 n-1 下溢,其机器数为 32 个 1,即 232-1,这是 unsigned 可表示的最大值。因此 i <= n-1 始终成立,循环不会结束。若把 i 和 n 都改为 int 型,则不会死循环:此时 n-1=-1,初始 i=0,循环条件不成立。
(2)f1(23) 和 f2(23) 返回值相等。f1(23) 的机器数为 00FFFFFFH,f2(23) 的机器数为 4B7FFFFFH。
(3)不相等。f(24)=33\,554\,431 的二进制形式为 25 个连续的 1,而单精度 float 只有 24 位有效数字,必须舍入,因此 f2(24) 得到 33 554 432.0,比 f1(24) 的 33 554 431 大 1。
(4)f1(31) 返回 -1 是因为 int 溢出,全 1 解释为 -1。使 f1(n) 与 f(n) 相等的最大 n 为 30。
(5)f2(127) 对应 +∞。使 f2(n) 不溢出的最大 n 为 126;使 f2(n) 精确的最大 n 为 23。