了解DBL_MAX

时间:2015-05-05 22:56:54

标签: c floating-point double double-precision

我刚刚阅读了IEEE 754标准,以了解single-precisiondouble-precision浮点的实现方式。

所以我写这篇文章来检查我的理解:

#include <stdio.h>
#include <float.h>

int main() {
    double foo = 9007199254740992; // 2^53
    double bar = 9007199254740993; // 2^53 + 1

    printf("%d\n\n", sizeof(double)); // Outputs 8. Good
    printf("%f\n\n", foo); // 9007199254740992.000000. Ok
    printf("%f\n", bar); // 9007199254740992.000000. Ok because Mantissa is 52 bits
    printf("%f\n\n", DBL_MAX); // ??

    return 0;
}

输出:

8

9007199254740992.000000

9007199254740992.000000

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000

我不明白的是,我希望输出的最后一行是:(2 ^ 53-1)* 2 ^(1024-52),但最后一行的数字大致相当于2 ^(2 ^ 10)。我错过了什么?如何准确计算DBL_MAX

编辑:关于DBL_MAX确切值的一点解释:

如在接受的答案中所解释的那样,指数的最大值是2 ^ 1023而不是2 ^ 1024。因此DBL_MAX完全值为: (2^53-1)*(2^(1023-52)) (因为预计它会略小于2 ^ 10,因为尾数略小于2)

2 个答案:

答案 0 :(得分:4)

Double表示为m*2^e,其中m是尾数,e是指数。对于指数,双打有11位。由于指数可以是负数,因此存在1023的偏移量。这意味着实际计算是m*2^(e-1023)。最大的11位数是2047。指数2047保留用于存储infNaN。这意味着最大的双倍是m*2^(2046-1023) = m*2^(1023)。尾数是一个介于1和2之间的数字。这意味着当m几乎为2时达到最大的双精度。所以我们有:

DBL_MAX = max(m)*2^1023 ~ 2*2^1023 = 2^1024 = 2^(2^10)

正如您所见here,这几乎是DBL_MAX的标准值。

答案 1 :(得分:1)

DBL_MAX是double可容纳的最大。它的值与尾数中的位数无关。

限制主要与最大指数有关。对于IEEE-754,它大约是1.8e + 308或2 ^ 1023。

定义通常为#define DBL_MAX 1.79769313486231470e+308