Math.random()在javascript中是如何工作的?

Math.random()在javascript中是如何工作的?,javascript,math,Javascript,Math,我最近发现了如何通过谷歌获得一个随机数,这让我思考Math.random()是如何工作的。所以在这里,我无法理解他们是如何做数学的。random()除非他们使用类似时间的东西。有人知道JavaScript的Math.random()或类似的东西是如何工作的吗?他们使用“类似时间的东西”是正确的。伪随机发生器通常使用系统时钟进行种子设定,因为这是一个不总是相同的数字的良好来源 一旦随机生成器中植入了一个数字,它将生成一系列数字,这些数字都取决于初始值,但其方式似乎是随机的 一个简单的随机生成器(不

我最近发现了如何通过谷歌获得一个随机数,这让我思考
Math.random()
是如何工作的。所以在这里,我无法理解他们是如何做数学的。random()除非他们使用类似时间的东西。有人知道JavaScript的
Math.random()
或类似的东西是如何工作的吗?

他们使用“类似时间的东西”是正确的。伪随机发生器通常使用系统时钟进行种子设定,因为这是一个不总是相同的数字的良好来源

一旦随机生成器中植入了一个数字,它将生成一系列数字,这些数字都取决于初始值,但其方式似乎是随机的

一个简单的随机生成器(不久前在编程语言中实际使用)是在如下算法中使用素数:

rnd = (rnd * 7919 + 1) & 0xffff;
uint32_t state0 = 1;
uint32_t state1 = 2;
uint32_t mwc1616() {
  state0 = 18030 * (state0 & 0xffff) + (state0 >> 16);
  state1 = 30903 * (state1 & 0xffff) + (state1 >> 16);
  return state0 << 16 + (state1 & 0xffff);
这将产生一系列来回跳跃的数字,看起来是随机的。例如:

seed = 1337
36408
22089
7208
63833
14360
11881
41480
13689
6648
Javascript中的random generator稍微复杂一点(以提供更好的分布),使用更大的数字(因为它必须生成一个大约60位而不是16位的数字),但它遵循相同的基本原理。

Math.random()返回一个带正号的数值,大于或等于0但小于1,使用依赖于实现的算法或策略,在该范围内以近似均匀分布随机或伪随机选择

下面是V8的实现:

uint32_t V8::Random() {

    // Random number generator using George Marsaglia's MWC algorithm.
    static uint32_t hi = 0;
    static uint32_t lo = 0;

    // Initialize seed using the system random(). If one of the seeds
    // should ever become zero again, or if random() returns zero, we
    // avoid getting stuck with zero bits in hi or lo by reinitializing
    // them on demand.
    if (hi == 0) hi = random();
    if (lo == 0) lo = random();

    // Mix the bits.
    hi = 36969 * (hi & 0xFFFF) + (hi >> 16);
    lo = 18273 * (lo & 0xFFFF) + (lo >> 16);
    return (hi << 16) + (lo & 0xFFFF);
}
uint32_t V8::Random(){
//使用George Marsaglia的MWC算法的随机数生成器。
静态uint32_t hi=0;
静态uint32_t lo=0;
//使用系统随机()初始化种子。如果其中一个种子
//如果再次变为零,或者如果random()返回零,则
//通过重新初始化,避免在hi或lo中被零位卡住
//按需购买。
如果(hi==0)hi=random();
如果(lo==0)lo=random();
//把碎片混合起来。
hi=36969*(hi&0xFFFF)+(hi>>16);
lo=18273*(lo&0xFFFF)+(lo>>16);
返回(hi见:

直到最近(直到版本4.9.40),V8选择的PRNG是MWC1616(带进位的乘法,结合两个16位部分)。它使用64位内部状态,大致如下所示:

rnd = (rnd * 7919 + 1) & 0xffff;
uint32_t state0 = 1;
uint32_t state1 = 2;
uint32_t mwc1616() {
  state0 = 18030 * (state0 & 0xffff) + (state0 >> 16);
  state1 = 30903 * (state1 & 0xffff) + (state1 >> 16);
  return state0 << 16 + (state1 & 0xffff);
uint32\u t state0=1;
uint32_t state1=2;
uint32_t mwc1616(){
state0=18030*(state0&0xffff)+(state0>>16);
state1=30903*(state1&0xffff)+(state1>>16);
返回状态0 17;
s1^=s0;
s1^=s0>>26;
状态1=s1;
返回状态0+state1;
}
在我们意识到这个问题后的几天内,新的实现在V8 4.9.41.0中登陆。它将在Chrome 49中提供。Firefox和Safari也切换到xorshift128+。


<script>

function generateRandom(){  //  Generate and return a random number
    var num = Math.random();
    num = (Math.round((num*10)))%10;
    return num;
}

function generateSum(){ //  Generate a problem
    document.getElementById("ans").focus();
    var num1 = generateRandom();
    var num2 = generateRandom();
    document.getElementById("num1").innerHTML = num1;
    document.getElementById("num2").innerHTML = num2;
    document.getElementById("pattern1").innerHTML = printPattern(num1);
    document.getElementById("pattern2").innerHTML = printPattern(num2);

}

function printPattern(num){ //  Generate the star pattern with 'num' number of stars
    var pattern = "";
    for(i=0; i<num; i++){
        if((i+1)%4 == 0){
            pattern = pattern+"*<br>";
        }
        else{
            pattern = pattern+"*";
        }
    }
    return pattern;
}

function checkAns(){    //  Check the answer and give the response
    var num1 = parseInt(document.getElementById("num1").innerHTML);
    var num2 = parseInt(document.getElementById("num2").innerHTML);
    var enteredAns = parseInt(document.getElementById("ans").value);
    if ((num1+num2) == enteredAns){
        document.getElementById("patternans").innerHTML = printPattern(enteredAns);
        document.getElementById("patternans").innerHTML += "<br>Correct";
    }
    else{
        document.getElementById("patternans").innerHTML += "Wrong";
        //remove + mark to remove the error

    }
}

function newSum(){
    generateSum();
    document.getElementById("patternans").innerHTML = "";
    document.getElementById("ans").value = "";
}

</script>
函数generateRandom(){//生成并返回一个随机数 var num=Math.random(); num=(数学四舍五入((num*10))%10; 返回num; } 函数generateSum(){//生成一个问题 document.getElementById(“ans”).focus(); var num1=generateRandom(); var num2=generateradom(); document.getElementById(“num1”).innerHTML=num1; document.getElementById(“num2”).innerHTML=num2; document.getElementById(“pattern1”).innerHTML=printPattern(num1); document.getElementById(“pattern2”).innerHTML=printPattern(num2); } 函数printPattern(num){//生成星号为'num'的星型图案 var模式=”;
对于(i=0;i您可能希望本文作为参考:

顺便说一句,最近我也对这个问题很好奇,然后阅读了NodeJS的源代码。我们可以从Google V8中了解一个可能的实现:

random(
MathRandom::RefillCache
函数)的主项:

种子是如何初始化的?另请参见此处:

按键功能是(
XorShift128
function):

在这个头文件中,有一些参考文件:

// See Marsaglia: http://www.jstatsoft.org/v08/i14/paper
// And Vigna: http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf

它的工作方式并不是由规范规定的。它可能是大多数运行时中的某种类型。请参阅或参阅注释:ECMA说明中指出,该数字可以随机生成,也可以伪随机生成,并且对于不同的平台可能有所不同。如果可能重复,您应该在那里发布答案……您能提供来源吗?