计算浮点精度(K& R 2-1)

时间:2015-02-09 19:01:31

标签: c floating-point floating-accuracy kernighan-and-ritchie

我发现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的倍数的进展最终应该确定有效数的值,但是我试图追踪一些小数字以检查它应该如何工作并且找不到正确的值......

=============================================== =======================

该程序所依据的概念是什么,并且该程序变得更精确,因为必须找到更长的非整数?

1 个答案:

答案 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类型表示的数字。