我是靠谱客的博主 无心天空,最近开发中收集的这篇文章主要介绍JavaScript生成随机数为什么用(9301,49297,233280)作为基数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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 m1 之间的随机数。这个公式中的参数需要满足Hull-Dobell定理,即:

  1. c c c m m m互质
  2. a − 1 a - 1 a1可以被 m m m的所有质因数整除
  3. 如果 m m m 是4的倍数, m − 1 m - 1 m1 也必须是4的倍数

三个基数

满足以上三个条件的数有很多,但是为什么要挑a = 9301c = 49297m = 233280这三个呢?从工程的角度看,acm三个值的取值需要满足下面两个要求:

  1. (m−1) a + c要足够的小,避免溢出
  2. 满足良好的随机性。评估方法为Knunth’s Spectral Test。

此时,最优的c值需要满足:

  1. 是质数
  2. 接近 ( 1 2 − 1 6 3 ) m (frac{1}{2} - frac{1}{6}sqrt{3})m (21613 )m

用前文说的Spectral Test方式遍历一下 [ 0 , 2 32 − 1 ] [0, 2^{32}-1] [0,2321] 区间内的整数,可以得到下表:
在这里插入图片描述
从表上看,a = 9301c = 49297m = 233280是在int类型的取值范围内满足条件的最大组合

最后

以上就是无心天空为你收集整理的JavaScript生成随机数为什么用(9301,49297,233280)作为基数的全部内容,希望文章能够帮你解决JavaScript生成随机数为什么用(9301,49297,233280)作为基数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部