Понимание DBL_MAX

Я просто прочитал о стандарте IEEE 754, чтобы понять, как реализованы числа с плавающей запятой одинарной и двойной точности.

Поэтому я написал это, чтобы проверить мое понимание:

#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 ответа

Решение

Двойные представлены как m*2^e где m это мантисса и e это показатель. Двойники имеют 11 бит для показателя степени. Поскольку показатель степени может быть отрицательным, есть смещение 1023, Это означает, что реальный расчет m*2^(e-1023), Наибольшее 11-битное число 2047, Экспонента 2047 зарезервировано для хранения inf а также NaN, Это означает, что самый большой дубль 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,

DBL_MAX это наибольшее значение, которое может содержать двойник. Его значение не связано с количеством битов в мантиссе.

Предел в основном связан с максимальным показателем. Для IEEE-754 это примерно 1,8e+308 или 2^1023.

Определение обычно #define DBL_MAX 1.79769313486231470e+308

Другие вопросы по тегам