可以存储在double中的最大整数

Fra*_*ger 208 floating-point double types ieee-754

什么是最大的"非浮动"整数,可以存储在IEEE 754 double类型而不会丢失精度?

Ste*_*sop 477

可以存储在double中而不会丢失精度的最大/最大整数与double的最大可能值相同.也就是说,DBL_MAX或大约1.8×10 308(如果你的双倍是IEEE 754 64位双倍).这是一个整数.它完全代表了.你还想要什么?

继续,问我最大的整数是什么,这样它和所有较小的整数都可以存储在IEEE 64位双精度而不会丢失精度.IEEE 64位双尾有52位尾数,所以我认为它是2 53:

  • 2 53 + 1无法存储,因为开头的1和末尾的1之间有太多的零.
  • 可以存储少于2 53的任何内容,其中52位明确存储在尾数中,然后指数实际上为您提供另一个.
  • 显然可以存储2 53,因为它的功率小于2.

或者另一种看待它的方法:一旦偏离指数被取消,并忽略符号位与问题无关,则double存储的值是2的幂,加上52位整数乘以2 指数 - 52.因此,使用指数52,您可以存储从2 52到2 53  - 1的所有值.然后使用指数53,您可以在2 53之后存储的下一个数字是2 53 + 1×2 53 - 52.因此,精度损失首先发生在2 53 + 1.

  • +1好的工作注意到这个问题并不真正意味着提问者可能想要的并提供两个答案("技术上正确"和"可能预期"). (117认同)
  • 或者"搞乱"和"试图帮助",因为我倾向于称呼他们:-) (59认同)
  • 我的意思是更小,这正是我说的更小的意思:-) -1,000,000小于1,但它并不小. (12认同)
  • 你并不是指"所有较小的整数",你的意思是所有整数相等或较小.因为在2 ^ 53以下有很多负整数,并且不能用双精度表示. (11认同)
  • 我向托尼小马鞠躬,而不是其他人. (8认同)
  • @Pacerier:它是一个整数,它的表示为"double"是精确的,它是具有该属性的最大整数.因此它回答了这个问题的标题,"可以存储在双精度中的最大整数".我不认为我可以进一步解释,解释一个笑话只有那么多里程. (2认同)
  • 成为smartass的额外奖励. (2认同)
  • 有趣的是,没有人提到这个问题与 Javascript 的联系。Javascript 没有整数类型,一切都是浮点数(双精度),因此这个答案为您提供了 Javascript 中整数的范围。 (2认同)

pmg*_*pmg 70

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;
}
Run Code Online (Sandbox Code Playgroud)

结果

9007199254740991
9007199254740992
9007199254740992

  • 假设它将"接近"但小于2 ^ N,那么更快的测试是`double dbl = 1; while(dbl + 1!= dbl)dbl*= 2; while(dbl == --dbl);`产生相同的结果 (7认同)
  • 也许表明2 ^ 53 = 9,007,199,254,740,992. (5认同)
  • @Seph是什么...?没有?`while(dbl == --dbl)`将永远循环或根本不循环.:)(在这种情况下,完全没有,因为它是2 ^ N).你必须从下面接近它.它确实也会导致一个小于预期的结果(因为while循环中的一个检查减少了dbl).并且它取决于执行的顺序,如果在评估左侧之前或之后完成减量(据我所知,这是未定义的).如果它是前者,它将永远是真实的并永远循环. (4认同)
  • 这很难争论!不错的实验 (2认同)

Car*_*icz 25

维基百科可以在相同的上下文中说明与IEEE 754的链接:

在典型的计算机系统中,"双精度"(64位)二进制浮点数具有53位的系数(其中一个暗示),11位的指数和一个符号位.

2 ^ 53刚刚超过9*10 ^ 15.

  • @San Jacinto - "这没用",过于苛刻.答案是非常有用的,如果它包含典型计算机系统确实使用IEEE 754表示的评论,那就没那么有用了. (14认同)

Sim*_*ber 16

可以在IEEE 754 double(64位)中表示的最大整数与该类型可以表示的最大值相同,因为该值本身是整数.

这表示为0x7FEFFFFFFFFFFFFF:由以下部分组成:

  • 符号位0(正)而不是1(负)
  • 最大指数0x7FE(2046表示减去偏差后的1023)而不是0x7FF(2047表示a NaN或无穷大).
  • 最大尾数0xFFFFFFFFFFFFF是52位全1.

在二进制中,值是隐式1,后跟来自尾数的另外52个,然后是指数的971个零(1023 - 52 = 971).

确切的十进制值是:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

这大约是1.8 x 10 308.

  • 如果它和零之间的所有值都可以连续表示,那么它可以表示的最大值又如何呢? (2认同)

Dol*_*hin 8

你需要看一下尾数的大小.IEEE 754 64位浮点数(具有52位,加上1隐含)可以精确地表示绝对值小于或等于2 ^ 53的整数.

  • 它也可以完全代表2 ^ 53 :-) (8认同)

Jay*_*Jay 5

1.7976931348623157×10 ^ 308

http://en.wikipedia.org/wiki/Double_precision_floating-point_format

  • 在讨论这个毫无希望的沉没答案时,我们只涉及语义。没错,该数字可以准确表示,从而满足问题的要求。但是我们都知道,这是一个险峻的小岛,几乎是一个未命中的海洋,我们大多数人正确地将这个问题插值为“最大的数字,超出这个数字就会降低效率”。啊,CompSci是一门精确的科学难道不是很好吗?:) (6认同)
  • @所有人:1.7976931348623157×10 ^ 308 **是一个精确的整数。你们都需要参加数学补习班吗? (4认同)
  • 引用此答案会更好。 (2认同)
  • @Carl,如果整数在左边超出零,则将其精确存储。 (2认同)
  • @DanMoulding 1.7976931348623157×10 ^ 308是一个精确的整数,但是我敢肯定这个特定的整数不能精确地存储在双精度中。 (2认同)
  • 注意(以防万一有人链接到这个特定答案):西蒙·比伯的答案中提供了实际数字。 (2认同)

Jan*_*dal 5

确实,对于 64 位 IEEE754 double,可以精确表示 9007199254740992 == 2^53 以内的所有整数。

然而,还值得一提的是,所有超出 4503599627370496 == 2^52 的可表示数字都是整数。超过 2^52 时,测试它们是否是整数就变得毫无意义,因为它们都隐式舍入到附近的可表示值。

在 2^51 到 2^52 范围内,唯一的非整数值是以“.5”结尾的中点,这意味着计算后的任何整数测试都必须预期会产生至少 50% 的错误答案。

在 2^51 以下,我们还有“.25”和“.75”,因此将数字与其四舍五入的对应数字进行比较以确定它是否可能是整数开始有意义。

TLDR:如果要测试计算结果是否为整数,请避免大于 2251799813685248 == 2^51 的数字