Понимание 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