我发现Stevens Computing Services – K & R Exercise 2-1对K& R 2-1的答案非常彻底。完整代码的这一部分计算C编程语言中float
类型的最大值。
不幸的是,我对float
值的理解非常有限。我知道它们是由有效数字(尾数...)和一个2的幂的量值组成的。
#include <stdio.h>
#include <limits.h>
#include <float.h>
main()
{
float flt_a, flt_b, flt_c, flt_r;
/* FLOAT */
printf("\nFLOAT MAX\n");
printf("<limits.h> %E ", FLT_MAX);
flt_a = 2.0;
flt_b = 1.0;
while (flt_a != flt_b) {
flt_m = flt_b; /* MAX POWER OF 2 IN MANTISSA */
flt_a = flt_b = flt_b * 2.0;
flt_a = flt_a + 1.0;
}
flt_m = flt_m + (flt_m - 1); /* MAX VALUE OF MANTISSA */
flt_a = flt_b = flt_c = flt_m;
while (flt_b == flt_c) {
flt_c = flt_a;
flt_a = flt_a * 2.0;
flt_b = flt_a / 2.0;
}
printf("COMPUTED %E\n", flt_c);
}
据我所知,后一部分基本上通过三变量算法检查2的幂是否可能提高有效数。第一部分怎么样?
我可以看到2的倍数的进展最终应该确定有效数的值,但是我试图追踪一些小数字以检查它应该如何工作并且找不到正确的值......
=============================================== =======================
该程序所依据的概念是什么,并且该程序变得更精确,因为必须找到更长的非整数?
答案 0 :(得分:3)
第一个循环通过找到最小功率2来确定对有效数字有贡献的位数,以便向其添加1(使用浮点运算)无法更改其值。如果它是2的n
幂,则有效数字使用n
位,因为使用n
位,您可以表示从0到2 ^ {{1}的所有整数} - 1,但不是2 ^ n
。因此,2 ^ n
的浮点表示必须具有足够大的指数,以使(二进制)单位数字不重要。
由于同样的原因,找到了n
表示比单位精度差的2的第一个幂, 的最大float
值具有单位精度为1减。 该值记录在变量float
中。
第二个循环然后通过从最大单位精度值开始测试最大指数,并重复加倍(从而将指数增加1),直到它发现结果不能通过将其减半来转换回来。最大flt_m
是最终加倍之前的值。
顺便说一下,请注意以上所有内容都假设了一个base-2浮点表示。您不太可能碰到任何不同的东西,但C实际上并不要求任何特定的表示。
关于问题的第二部分,
这个程序是否会变得更精确,因为必须找到更长的非整数?
该程序注意避免丢失精度。它确实假设一个二进制浮点表示,如您所描述的,但它将正常工作,无论这种表示的有效位数或指数中的位数。不涉及非整数,但程序已经处理了比单位精度更差的数字,并且数字大于可以用float
类型表示的数字。