Answers:
可以存储在double中而不丢失精度的最大/最大整数与double的最大可能值相同。即DBL_MAX
约1.8× 10308(如果您的double是IEEE 754 64位double)。这是一个整数。准确地表示出来。您还想要什么?
继续,问我最大的整数是什么,这样它和所有较小的整数可以存储在IEEE 64位double中,而不会丢失精度。IEEE 64位双精度数有52位尾数,所以我认为是2 53:
或以另一种方式看待它:一旦去除了指数的偏差,并且忽略了与问题无关的符号位,则双精度值存储的值为2的幂,再加上一个52位整数乘以2 指数-52。因此,对于指数52,您可以存储从2 52到2 53 − 1的所有值。然后对于指数53,在2 53之后可以存储的下一个数字是2 53 +1×2 53-52。因此精度损失首先出现在2 53 + 1处。
9007199254740992(即9,007,199,254,740,992),没有保证:)
程序
#include <math.h>
#include <stdio.h>
int main(void) {
double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
while (dbl + 1 != dbl) dbl++;
printf("%.0f\n", dbl - 1);
printf("%.0f\n", dbl);
printf("%.0f\n", dbl + 1);
return 0;
}
结果
9007199254740991 9007199254740992 9007199254740992
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);
,得出相同的结果
while (dbl == --dbl)
将永远循环或根本不循环。:)(在这种情况下,根本没有,因为它是2 ^ N)。您必须从下面接近它。实际上,它也会导致比预期结果少一(因为while循环中的一检查减少了dbl)。而且,递减是在评估左侧之前还是之后进行的,这取决于执行顺序(据我所知这是未定义的)。如果是前者,它将始终为真并永远循环。
while (dbl + 1 != dbl) dbl++;
在dbl + 1 != dbl
使用可评估long double
的数学-考虑FLT_EVAL_METHOD == 2
。这可能会陷入无限循环。
Wikipedia在同一上下文中也提到了指向IEEE 754的链接:
在典型的计算机系统上,“双精度”(64位)二进制浮点数的系数为53位(暗含其中之一),指数为11位和一个符号位。
2 ^ 53刚好超过9 * 10 ^ 15。
在IEEE 754 double(64位)中可以表示的最大整数与该类型可以表示的最大值相同,因为该值本身就是整数。
表示为0x7FEFFFFFFFFFFFFF
,由以下组成:
0x7FE
(2046代表减去偏差后的1023)而不是0x7FF
(2047代表a NaN
或无穷大)。0xFFFFFFFFFFFFF
均为52位1。用二进制表示,值是隐式1,尾数是52,然后是指数的971个零(1023-52 = 971)。
确切的十进制值为:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766871171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274834826360284
这大约是1.8 x 10 308。
1.7976931348623157×10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
from <float.h>
应该至少给出一个合理的近似值。因为带小数点的数字是交易,它的真正存储在二进制,你大概可以存储的东西有点不失精度较大,但到底有多少还很难说。我想您应该能够从FLT_RADIX
和中找出答案DBL_MANT_DIG
,但是我不确定我是否完全相信结果。
double
直接对应于特定IEEE类型的,但这不是必需的,并且在撰写此答案时,问题也没有提到特定的IEEE类型。