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说明中指出,该数字可以随机生成,也可以伪随机生成,并且对于不同的平台可能有所不同。如果可能重复,您应该在那里发布答案……您能提供来源吗?