是否有可能在JavaScript中播种随机数生成器(Math.random) ?
当前回答
对于一个固定的种子有一个简单的方法:
function fixedrandom(p){
const seed = 43758.5453123;
return (Math.abs(Math.sin(p)) * seed)%1;
}
其他回答
对于0到100之间的数。
Number.parseInt(Math.floor(Math.random() * 100))
注意:尽管(或者说,因为)简洁和明显的优雅,这个算法在随机性方面绝不是一个高质量的算法。看看这个答案中列出的例子,会有更好的结果。
(最初改编自另一个答案的评论中提出的一个聪明的想法。)
var seed = 1;
function random() {
var x = Math.sin(seed++) * 10000;
return x - Math.floor(x);
}
您可以将seed设置为任何数字,只是避免为零(或Math.PI的任何倍数)。
在我看来,这个解决方案的优雅之处在于没有任何“神奇”数字(除了10000,它代表了您必须丢弃的最小数字数量,以避免奇怪的模式-请参阅值为10,100,1000的结果)。简洁也很好。
它比Math.random()稍微慢一点(2或3倍),但我相信它与任何其他用JavaScript编写的解决方案一样快。
在PHP中,有一个srand(seed)函数,它为特定的seed生成固定的随机值。 但是,在JS中,没有这样的内置函数。
然而,我们可以编写简单而简短的函数。
第一步:选择一些种子(固定编号)。 Var种子= 100; Number应为正整数且大于1,详见步骤2。
第2步:在Seed上执行Math.sin()函数,它将给出该数字的sin值。将这个值存储在变量x中。
var x;
x = Math.sin(seed); // Will Return Fractional Value between -1 & 1 (ex. 0.4059..)
sin()方法返回一个介于-1到1之间的分数值。我们不需要负数,因此,在第一步中选择大于1的数字。
步骤3:返回值是-1到1之间的分数值。所以这个值乘以10使它大于1。
x = x * 10; // 10 for Single Digit Number
第四步:将数值乘以10,得到额外的数字
x = x * 10; // Will Give value between 10 and 99 OR
x = x * 100; // Will Give value between 100 and 999
按要求的数字相乘。
结果将是十进制的。
第五步:通过Math's Round (Math. Round())方法删除小数点后的值。
x = Math.round(x); // This will give Integer Value.
第六步:用数学把负值转化为正数(如果有的话)。abs方法
x = Math.abs(x); // Convert Negative Values into Positive(if any)
解释。最终代码
var seed = 111; // Any Number greater than 1
var digit = 10 // 1 => single digit, 10 => 2 Digits, 100 => 3 Digits and so. (Multiple of 10)
var x; // Initialize the Value to store the result
x = Math.sin(seed); // Perform Mathematical Sin Method on Seed.
x = x * 10; // Convert that number into integer
x = x * digit; // Number of Digits to be included
x = Math.round(x); // Remove Decimals
x = Math.abs(x); // Convert Negative Number into Positive
干净和优化的函数代码
function random_seed(seed, digit = 1) {
var x = Math.abs(Math.round(Math.sin(seed++) * 10 * digit));
return x;
}
然后调用此函数using Random_seed (any_number, number_of_digits)any_number必须且应该大于1。number_of_digits是可选参数,如果没有传递,将返回1 Digit。
random_seed(555); // 1 Digit
random_seed(234, 1); // 1 Digit
random_seed(7895656, 1000); // 4 Digit
没有,但这里有一个简单的伪随机生成器,一个我从维基百科改编的Multiply-with-carry的实现(已经被删除了):
var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;
// Takes any integer
function seed(i) {
m_w = (123456789 + i) & mask;
m_z = (987654321 - i) & mask;
}
// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
function random()
{
m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
result /= 4294967296;
return result;
}
不,不可能为Math.random()提供种子,但是编写自己的生成器相当容易,或者更好的是使用现有的生成器。
请看:这个相关的问题。
另外,请参阅David Bau的博客了解更多关于播种的信息。
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 使用该集合的原因。种子功能
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?
- jQuery有不聚焦的方法吗?