Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用浮点源实现整数的均匀分布_Javascript_Algorithm_Random_Floating Point_Statistics - Fatal编程技术网

Javascript 使用浮点源实现整数的均匀分布

Javascript 使用浮点源实现整数的均匀分布,javascript,algorithm,random,floating-point,statistics,Javascript,Algorithm,Random,Floating Point,Statistics,在JavaScript中获取[0,n]范围内的随机整数的标准方法是使用Math.floor(Math.random()*n),该语言或任何其他语言仅提供返回[0,1]范围内浮点值的random()函数 假设我们是在有理数集上操作,那么这背后的数学就很简单了。问题是:在IEEE-754浮点数的复杂情况下,得到的分布真的是均匀的吗 考虑到一个浮点数和下一个更大的浮点数之间的差距随着它们的增大而增大,我认为这应该会导致对较小数字的某种偏见。根据 Math.random的功能 返回大于或等于0的带正号的

在JavaScript中获取[0,n]范围内的随机整数的标准方法是使用
Math.floor(Math.random()*n)
,该语言或任何其他语言仅提供返回[0,1]范围内浮点值的random()函数

假设我们是在有理数集上操作,那么这背后的数学就很简单了。问题是:在IEEE-754浮点数的复杂情况下,得到的分布真的是均匀的吗

考虑到一个浮点数和下一个更大的浮点数之间的差距随着它们的增大而增大,我认为这应该会导致对较小数字的某种偏见。

根据

Math.random的功能

返回大于或等于0的带正号的数值 但小于1,随机或伪随机选择,约 在该范围内均匀分布,使用 依赖于实现的算法或策略。此函数不需要 争论

查看此帖子:

这已经超出了我的理解范围,对不起,我没有什么可以贡献的了

假设random()返回一个介于0到1之间的数字

如果结果是一个单精度浮点,那么基于尾数的熵只有23位

如果结果是双精度浮点,那么基于尾数的熵只有52位

所以地板(random()*N)只有在N小于2^24或2^53时才是均匀的


编辑这里有一些关于浮点最大连续整数的信息

我假设您的评论“一个浮点数和下一个更高的浮点数之间的差距随着它们变大而增大”是基于以下几点:

在IEEE-754中,你有一个固定大小的尾数,它允许在[1,2]范围内有均匀的“随机”值,比如说,在[2,4]中有相等数量的可能值,这是一个范围的两倍,因此我们得到可能值之间的2倍间距,同样是[4,8]的两倍,等等

现在,我还没有检查“,,使用依赖于实现的算法或策略”背后的技术细节,当他们谈论为其生成的随机数的属性时[0,1),但由于上述考虑非常琐碎,我假设随机生成器程序员已经意识到了这一点,并使用“依赖于实现的算法…”来处理它


因此,作为一个天真的人,我相信关于(我的假设)你怀疑的理由没有什么好担心的。事实上,我可能会认为,如果你能为尾数生成统一和随机的值,那么总是设置相同的指数,这样值就属于[1,2),从所有值中减去1,得到[0,1]的适当分布。

如果
Math.random
(或等效值)从与范围内的浮点数对应的位模式中生成均匀分布的位模式[0,1],那么它将产生一个极有偏差的样本。[0.25,0.5]中的可表示浮点数与[0.5,1.0]中的可表示浮点数一样多,这与[0.5,1.0]中的可表示浮点数相同[0.125,0.25]等等。简言之,均匀分布的位模式只会导致千分之一的值介于0.5和1.0之间(假设为双精度浮点数)

幸运的是,
Math.random
并不是这样做的。获得均匀分布数字(而不是位模式)的一种简单方法是在[1.0,2.0]中生成均匀分布的位模式,然后减去1.0;这是一种相当常见的策略


无论如何,
Math.floor(Math.random()*n)的最终结果由于量化偏差,除非
n
是2的幂,否则
的分布不是很均匀。
Math.random
可能返回的浮点值的数量是2的幂,如果
n
不是2的幂,则不可能精确分布可能的浮点值在中的所有整数值上均匀地[0,n)。如果
Math.random
返回一个双精度浮点数,并且
n
不是很大,这个偏差很小,但它确实存在。

不,对于
n
的大多数值,结果分布不会完全一致。对于较小的值,它将非常接近一致,以至于您会有一个困难的time从均匀分布中检测任何差异,但当
n
变得更大时,偏差会变得明显

下面是一些Python代码(抱歉,不是JavaScript,但原理是一样的):

这将在
[0,6755399441055744)
,将这些整数中的每一个减少到模3,并计算余数为0、1或2的次数。如果我们均匀地生成这些整数,我们期望模3的余数大致均匀分布,因此我们期望计数相似

以下是在我的机器上运行此操作的示例结果:

Counter({1: 3751915, 0: 3334643, 2: 2913442})
也就是说,
1
的剩余部分比
0
的剩余部分发生的可能性大得多,而
0
的剩余部分又比
2
的剩余部分发生的可能性大得多。这里的差异太大,无法用随机变化来解释

那么出了什么问题呢?Python的
random()
函数的质量相对较高,基于,因此我们不太可能看到由基本随机数生成器产生的统计问题。现在发生的是
random()
生成了2^53(大致)中的一个同样可能的结果-对于
[0,2^53)
范围内的某个整数
x
,每个结果都是一个数的形式
x/2^53
。现在在
badrand中
Counter({1: 3751915, 0: 3334643, 2: 2913442})