我刚刚阅读了IEEE 754标准,以了解single-precision和double-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)
答案 0 :(得分:4)
Double表示为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)
正如您所见here,这几乎是DBL_MAX
的标准值。
答案 1 :(得分:1)
DBL_MAX
是double可容纳的最大值。它的值与尾数中的位数无关。
限制主要与最大指数有关。对于IEEE-754,它大约是1.8e + 308或2 ^ 1023。
定义通常为#define DBL_MAX 1.79769313486231470e+308