0.0到1.0之间有多少个双数?

pol*_*nts 92 random floating-point precision double

这是我多年来一直想到的事情,但我从来没有花时间问过.

许多(伪)随机数生成器生成0.0到1.0之间的随机数.在数学上,此范围内有无限数,但是double是浮点数,因此具有有限的精度.

所以问题是:

  1. double在0.0和1.0之间有多少个数字?
  2. 是否有1到2之间的数字?100到101之间?在10 ^ 100和10 ^ 100 + 1之间?

注意:如果它有所不同,我double特别感兴趣的是Java的定义.

Ale*_*lli 67

Java doubleIEEE-754格式,因此它们具有52位分数; 在任何两个相邻的2的幂之间(包括一个并且不包括下一个),因此将存在2到52次幂的不同doubles(即,4503599627370496).例如,这是double包括在0.5和1.0之间的不同s 的数量,并且恰好许多也在1.0包括和2.0排除之间,等等.

计算doubles介于0.0和1.0之间比在2的幂之间计算更难,因为在该范围内包含许多两个幂,并且还有一个涉及非规范化数字的棘手问题.指数的11位中的10位覆盖了所讨论的范围,因此,包括非规范化数字(我认为有几种NaN),你有两倍于2 double的幂之间的s的1024倍- 不超过2**62总数.不包括非规范化和c,我相信计数将是1023次2**52.

对于像"100到100.1"这样的任意范围,它甚至更难,因为上限不能精确地表示为double(不是两个幂的精确倍数).作为一个方便的近似,因为2的幂之间的进展是线性的,你可以说所述范围是0.1 / 64周围两个(64和128)的幂之间的跨度的th,所以你期望

(0.1 / 64) * 2**52
Run Code Online (Sandbox Code Playgroud)

不同的doubles - 来7036874417766.4004......给或拿一两个;-).

  • @polygene,是和是 - 具体来说,大约四分之一的可能值(对于任何基数和指数与分数长度的任何"正常"浮点表示)介于0.0和1.0之间(1.0和无穷大之间的另一个四分之一,以及剩下一半在实轴的负半部分).基本上,指数值的一半(具有正常偏差,在其范围内的一半)代表基数的负幂,因此数字<1.0. (9认同)
  • @polygenelubricants:对于许多应用程序,0到1之间的范围比100到101之间的范围更重要,更有趣,这就是为什么它获得更大的值.例如,在物理学中,你经常需要处理像牛顿的重力常数6.67e-11那样可笑的小值.具有良好的精度比100和101之间更有用.阅读http://floating-point-gui.de/以获取更多信息. (8认同)
  • @Alex:所以让我直截了当:可能只有'2**64'可能的双值(因为它是64位类型),显然这些值的巨大比例介于'0..1'之间? (4认同)

Ste*_*non 41

double表示在...之间0x00000000000000000x3ff0000000000000位于区间[0.0,1.0]内的每个值.这是(2 ^ 62 - 2 ^ 52)个不同的值(加上或减去一对,取决于您是否计算端点).

区间[1.0,2.0]对应于0x3ff0000000000000和之间的表示0x400000000000000; 这是2 ^ 52个不同的值.

区间[100.0,101.0]对应于0x4059000000000000和之间的表示0x4059400000000000; 这是2 ^ 46个不同的值.

10 ^ 100和10 ^ 100 + 1之间没有双打.这些数字中的任何一个都不能以双精度表示,并且它们之间没有双精度数.最接近的两个双精度数字是:

99999999999999982163600188718701095...
Run Code Online (Sandbox Code Playgroud)

10000000000000000159028911097599180...
Run Code Online (Sandbox Code Playgroud)


Mar*_*son 7

其他人已经解释过在[0.0,1.0]范围内有大约2 ^ 62个双打.
(不是真的令人吃惊:有近2 ^ 64个不同有限双打;其中一半是正的,和大约一半的那些是<1.0.)

但是你提到了随机数生成器:请注意,生成0.0到1.0之间数字的随机数生成器通常不会产生所有这些数字; 通常它只生成n/2 ^ 53形式的数字,其中n为整数(参见例如nextDouble的Java文档).因此通常只有大约2 ^ 53(+/- 1,取决于包括哪些端点)random()输出的可能值.这意味着永远不会生成[0.0,1.0]中的大多数双精度数.