我只是阅读了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),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
保留用于存储inf
和NaN
。这意味着最大的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
的标准值。