概述
JavaScript随机数生成器
// Found this seed-based random generator somewhere
// Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu)
var seed = 1;
/**
* return a random number based on a seed
* @param seed
* @returns {number}
*/
function getNextValue() {
seed = (seed * 9301 + 49297) % 233280;
return seed / (233280.0);
}
function setSeed(_seed_) {
seed = _seed_;
}
module.exports = {
nextValue: getNextValue,
seed: setSeed
};
线性同余生成器
上面的代码使用了一种叫线性同余生成器(LCG,Linear Congruential Generator)的随机数生成器。这类生成器使用的公式为:
I
n
+
1
=
a
I
n
+
c
(
m
o
d
m
)
I_{n+1} = aI_{n} + c (mod m)
In+1=aIn+c(modm)
生成的随机数最大周期为
m
m
m,生成
0
0
0 到
m
−
1
m-1
m−1 之间的随机数。这个公式中的参数需要满足Hull-Dobell定理,即:
- c c c 与 m m m互质
- a − 1 a - 1 a−1可以被 m m m的所有质因数整除
- 如果 m m m 是4的倍数, m − 1 m - 1 m−1 也必须是4的倍数
三个基数
满足以上三个条件的数有很多,但是为什么要挑a = 9301
,c = 49297
,m = 233280
这三个呢?从工程的角度看,acm三个值的取值需要满足下面两个要求:
- (m−1) a + c要足够的小,避免溢出
- 满足良好的随机性。评估方法为Knunth’s Spectral Test。
此时,最优的c值需要满足:
- 是质数
- 接近 ( 1 2 − 1 6 3 ) m (frac{1}{2} - frac{1}{6}sqrt{3})m (21−613)m
用前文说的Spectral Test方式遍历一下
[
0
,
2
32
−
1
]
[0, 2^{32}-1]
[0,232−1] 区间内的整数,可以得到下表:
从表上看,a = 9301
,c = 49297
,m = 233280
是在int类型的取值范围内满足条件的最大组合
最后
以上就是无心天空为你收集整理的JavaScript生成随机数为什么用(9301,49297,233280)作为基数的全部内容,希望文章能够帮你解决JavaScript生成随机数为什么用(9301,49297,233280)作为基数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复