pol*_*nts 92 random floating-point precision double
这是我多年来一直想到的事情,但我从来没有花时间问过.
许多(伪)随机数生成器生成0.0到1.0之间的随机数.在数学上,此范围内有无限数,但是double是浮点数,因此具有有限的精度.
所以问题是:
double在0.0和1.0之间有多少个数字?注意:如果它有所不同,我double特别感兴趣的是Java的定义.
Ale*_*lli 67
Java double是IEEE-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......给或拿一两个;-).
Ste*_*non 41
double表示在...之间0x0000000000000000且0x3ff0000000000000位于区间[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)
其他人已经解释过在[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]中的大多数双精度数.