简体   繁体   English

JavaScript中的Math.random和Web编程

[英]Math.random and web programming in JavaScript

According to this Stack Overflow thread , Math.random() in JavaScript depends on the browser or the operating system. 根据此Stack Overflow线程 ,JavaScript中的Math.random()取决于浏览器或操作系统。 Basically, it implies that JavaScript does not have a standard algorithm for generating uniform random variables. 基本上,这意味着JavaScript没有用于生成统一随机变量的标准算法。 This thread seems to suggest that Chrome's uniform random number algorithm is particularly bad. 该线索似乎表明Chrome的统一随机数算法特别糟糕。

In my program I try to understand how the user behaves based on some information plus random noise. 在我的程序中,我尝试根据一些信息以及随机噪声来了解用户的行为。 I use a Box-Muller transform on numbers generated by Math.random() to generate Gaussian random numbers. 我对Math.random()生成的数字使用Box-Muller变换来生成高斯随机数。 Does this mean that users using one browser will be experiencing different types of noise than others? 这是否意味着使用一种浏览器的用户将遭受与其他浏览器不同类型的噪声? Note I use Box Muller because I don't care about speed, but I know it can be particularly sensitive to how the pseudo random numbers are generated. 请注意,我使用Box Muller是因为我并不关心速度,但是我知道它对伪随机数的生成方式特别敏感。 There seems to be lots of threads about why Math.random() is bad, but not so much within the thread on what to actually use instead. 关于Math.random()为何不好的问题似乎有很多话题,但是关于实际使用的内容却没有太多话题。 What is the best practice? 最佳做法是什么? Is there something that I should particularly look out for because I am using Box-Muller to convert to Gaussian numbers? 因为我正在使用Box-Muller转换成高斯数,所以我应该特别注意些什么吗?

There's an xor-shift based RNG at http://en.wikipedia.org/wiki/Xorshift with good randomness properties that should port fairly readily to JavaScript: http://en.wikipedia.org/wiki/Xorshift上有一个基于xor-shift的RNG,具有良好的随机性,应该可以很容易地移植到JavaScript:

EDIT done: 编辑完成:

(function () {
    var x = 123456789;
    var y = 362436069;
    var z = 521288629;
    var w = 88675123;
    var f = Math.pow(2, -32);

    Object.defineProperty(Math, 'xor128', {
        value: function () {
            var t = x ^ (x << 11);
            x = y;
            y = z;
            z = w;
            w = w ^ (w >>> 19) ^ (t ^ (t >>> 8));

            return (w >>> 0) * f;  // convert to floating point          
        }
    });

})();

NB: this only uses 32 bits of the 128 generated to produce the floating point result. 注意:这仅使用生成的128位中的32位来产生浮点结果。 In theory you could combine another 20 bits from one of the other state variables to produce 52 bits of result. 从理论上讲,您可以将其他状态变量之一的另外20位组合起来以产生52位结果。

The most significant issue with it I can see is that it doesn't support seeding - it'll always generate the same sequence. 我看到的最重要的问题是它不支持播种-它将始终生成相同的序列。

A Box-Muller transform only works on uniformly distributed input. Box-Muller变换仅适用于均匀分布的输入。 According to MDN (last example), Math.random() will not generate uniformly distributed numbers. 根据MDN (最后一个示例), Math.random()将不会生成均匀分布的数字。

The ECMAScript specification says the following about Math.random() : ECMAScript规范Math.random()了以下说明:

Returns a Number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-dependent algorithm or strategy. 使用依赖于实现的算法或策略,返回一个正号的Number值,该值大于或等于0但小于1,在该范围内随机选择或伪随机选择,并且在该范围内具有近似均匀的分布。 This function takes no arguments. 此函数不带参数。

So, it's up to the browser. 因此,这取决于浏览器。 A browser might but doesn't have to implement a perfectly uniformly distributed random number generator. 浏览器可能但不必实现完全均匀分布的随机数生成器。

Therefore you cannot reliably implement a cross-browser Box-Muller transform in Javascript on the browser side using Math.random() 因此,您无法使用Math.random()在浏览器端的Javascript中可靠地实现跨浏览器的Box-Muller转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM