我只是阅读了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),2(10),但最后一行的数字大约等于2(2)。我错过了什么?如何精确计算DBL_MAX
编辑:关于DBL_MAX的确切值的解释很少:
正如公认的答案所解释的,指数的最大值是2^1023,而不是我所认为的2^1024因此DBL_MAX的确切值是:
(2^53-1)*(2^(1023-52))(正如预期的那样,尾数小于2^10,因为尾数小于2)

最佳答案

Double表示为m*2^e,其中m是尾数,e是指数。双精度数的指数为11位因为指数可以是负的,所以有一个1023的偏移量。这意味着真正的计算是m*2^(e-1023)。最大的11位数字是2047。指数2047保留用于存储infNaN。这意味着最大的double是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)

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

08-16 08:36