是否有可能在JavaScript中播种随机数生成器(Math.random) ?
当前回答
没有,但这里有一个简单的伪随机生成器,一个我从维基百科改编的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.seed = function(s) {
var mask = 0xffffffff;
var m_w = (123456789 + s) & mask;
var m_z = (987654321 - s) & mask;
return function() {
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;
}
}
var myRandomFunction = Math.seed(1234);
var randomNumber = myRandomFunction();
Antti Sykäri的算法很好,很短。我最初做了一个变种来取代JavaScript的Math。当你调用Math.seed(s)时是随机的,但随后Jason评论说返回函数会更好:
Math.seed = function(s) {
return function() {
s = Math.sin(s) * 10000; return s - Math.floor(s);
};
};
// usage:
var random1 = Math.seed(42);
var random2 = Math.seed(random1());
Math.random = Math.seed(random2());
这为您提供了JavaScript没有的另一个功能:多个独立的随机生成器。如果您希望同时运行多个可重复的模拟,这一点尤其重要。
对于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编写的解决方案一样快。
编写自己的伪随机生成器非常简单。
戴夫·斯科塞斯的建议是有用的,但正如其他人指出的那样,它并不是完全均匀分布的。
然而,这并不是因为sin的整数参数。这只是因为sin的范围,恰好是一个圆的一维投影。如果取圆的角度,它就会是均匀的。
所以用arg(exp(i * x)) / (2 * PI)代替sin(x)
如果你不喜欢线性顺序,可以把它和异或混合一下。实际因素也没有那么重要。
要生成n个伪随机数,可以使用以下代码:
function psora(k, n) {
var r = Math.PI * (k ^ n)
return r - Math.floor(r)
}
n = 42; for(k = 0; k < n; k++) console.log(psora(k, n))
还请注意,当需要真实熵时,不能使用伪随机序列。
推荐文章
- 我如何检查如果一个变量是JavaScript字符串?
- Java生成两个给定值之间的随机数
- 如何检测如果多个键被按下一次使用JavaScript?
- 如何通过history. pushstate获得历史变化的通知?
- 如何从枚举中选择一个随机值?
- 使用jQuery改变输入字段的类型
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?