#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;
}
7 回答
你需要看一下尾数的大小 . IEEE 754 64位浮点数(具有52位,加上1隐含)可以精确地表示绝对值小于或等于2 ^ 53的整数 .
1.7976931348623157×10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
来自
<float.h>
的DECIMAL_DIG
应至少给出一个合理的近似值 . 因为它处理十进制数字,并且它实际上存储在二进制中,你可以存储一些更大的东西而不会丢失精度,但确切地说有多少 . 我想你应该能够从FLT_RADIX
和DBL_MANT_DIG
中找到它,但是我完全相信结果 .可以存储在double中而不会丢失精度的最大/最大整数与double的最大可能值相同 . 也就是说,
DBL_MAX
或大约1.8×10308(如果你的双倍是IEEE 754 64位双倍) . 它完全代表了's an integer. It' . 你还想要什么?继续,问我最大的整数是什么,这样它和所有较小的整数都可以存储在IEEE 64位双精度而不会丢失精度 . 一个IEEE 64位双尾有52位尾数,所以我认为它是253:
253 1无法存储,因为开头的1和末尾的1之间有太多的零 .
可以存储少于253的任何内容,其中52位明确存储在尾数中,然后指数实际上为您提供另一个 .
253显然可以存储,因为它的功率小于2 .
或者另一种看待它的方式:一旦偏离指数被取消,并忽略符号位与问题无关,则double存储的值是2的幂,加上52位整数乘以2exponent - 52.因此,使用指数52,您可以存储从252到253的所有值 . 然后使用指数53,您可以在253之后存储的下一个数字是253 1×253 - 52.因此,精度损失首先发生在253 1 .
9007199254740992 (即9,007,199,254,740,992)无保证:)
程序
结果
维基百科在相同的上下文中有一个链接到IEEE 754:
2 ^ 53刚刚超过9 * 10 ^ 15 .
可以在IEEE 754 double(64位)中表示的最大整数与该类型可以表示的最大值相同,因为该值本身是整数 .
这表示为
0x7FEFFFFFFFFFFFFF
,它由以下部分组成:符号位0(正)而不是1(负)
最大指数
0x7FE
(2046表示减去偏差后的1023)而不是0x7FF
(2047表示NaN
或无穷大) .最大尾数
0xFFFFFFFFFFFFF
,即52位全1 .在二进制中,值是隐式1,后跟来自尾数的另外52个,然后是指数的971个零(1023 - 52 = 971) .
确切的十进制值是:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
这大约是1.8 x 10308 .