Javascript randomInt函数,可统一处理最小和最大安全整数的整个范围

Javascript randomInt函数,可统一处理最小和最大安全整数的整个范围,javascript,algorithm,random,integer,limit,Javascript,Algorithm,Random,Integer,Limit,要求和背景 我想要一个通用的randomInt函数,它可以处理一系列的值,包括到,并且返回的值是 因此,我从MDN开始,查看页面。他们给出了一个例子,似乎是均匀分布的 // Returns a random integer between min (included) and max (excluded) // Using Math.round() will give you a non-uniform distribution! function getRandomInt(min, max)

要求和背景

我想要一个通用的
randomInt
函数,它可以处理一系列的值,包括到,并且返回的值是

因此,我从MDN开始,查看页面。他们给出了一个例子,似乎是均匀分布的

// Returns a random integer between min (included) and max (excluded)
// Using Math.round() will give you a non-uniform distribution!
function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
但它附带了以下注释

请注意,JavaScript中的as数字是IEEE 754浮点数 通过四舍五入到最近的偶数行为,为 下面的函数(不包括Math.random()本身的函数)不是 准确的如果选择了非常大的边界(2^53或更高),则为 在极少数情况下,可计算通常排除的 上限

我想使用范围-(2^53-1)和2^53-1,因此我认为此注释不适用。然后我注意到
max-min
:对于我指定的较大范围,这将是一个问题:

示例-最大范围

Number.MAX_SAFE_INTEGER - Number.MIN_SAFE_INTEGER > Number.MAX_SAFE_INTEGER
解决方案1-不是解决方案

接下来,我将根据MDN示例和我的需求,进行一些研究,并提出以下代码

Number.MAX_SAFE_INTEGER=Number.MAX_SAFE_INTEGER | 9007199254740991;
Number.MIN_SAFE_INTEGER=Number.MIN_SAFE_INTEGER | |-Number.MAX_SAFE_INTEGER;
Number.toInteger=Number.toInteger | |函数(inputArg){
变量编号=+inputArg,
val=0;
如果(数字===数字){
如果(!number | | number===无穷大| | number====无穷大){
val=数字;
}否则{
val=(数字>0 | |-1)*数学地板(数学abs(数字));
}
}
返回val;
};
函数clapsFaint(编号){
返回Math.min(Math.max(Number.toInteger(Number)、Number.min\u SAFE\u INTEGER)、Number.max\u SAFE\u INTEGER);
}
//返回最小值(包含)和最大值(包含)之间的随机整数
//使用Math.round()将得到非均匀分布!
函数randomInt(最小值、最大值){
var tmp,
瓦尔;
if(arguments.length==1){
最大值=最小值;
最小值=0;
}
最小值=夹紧假动作(最小值);
max=夹紧假动作(max);
如果(最小值>最大值){
tmp=min;
最小值=最大值;
max=tmp;
}
tmp=最大值-最小值+1;
if(tmp>Number.MAX\u SAFE\u整数){
抛出新的RangeError('最大值和最小值之差大于Number.max\u SAFE\u整数:'+tmp);
}否则{
val=数学地板(数学随机()*tmp)+min;
}
返回val;
}

log(randomInt(Number.MIN\u SAFE\u INTEGER,Number.MAX\u SAFE\u INTEGER))为什么不调用Math.random()两次,每次使用26位?这是相当安全的范围内,它可以产生良好的均匀性

function random53() {
    var hi, lo, sign = 0;

    while (true) {
        hi = Math.floor(67108864 * Math.random());
        lo = Math.floor(67108864 * Math.random());

        if (hi >= 33554432) {
            sign = -1;
            hi -= 33554432;

            // Gotta throw out negative zero!
            if (0 === hi && 0 === lo) { continue; }
        }
        return sign * (hi * 67108864) + lo;
    }
}

一个有效的解决方案,我所走的路线是使用BigNumber库。我仍然觉得必须有一个解决方案来解决这个问题,而不必依赖于一个大数字库,但我还没有找到任何其他方法

console.log(窗口);
Number.MAX_SAFE_INTEGER=Number.MAX_SAFE_INTEGER | 9007199254740991;
Number.MIN_SAFE_INTEGER=Number.MIN_SAFE_INTEGER | |-Number.MAX_SAFE_INTEGER;
Number.toInteger=Number.toInteger | |函数(inputArg){
变量编号=+inputArg,
val=0;
如果(数字===数字){
如果(!number | | number===无穷大| | number====无穷大){
val=数字;
}否则{
val=(数字>0 | |-1)*数学地板(数学abs(数字));
}
}
返回val;
};
函数clapsFaint(编号){
返回Math.min(Math.max(Number.toInteger(Number)、Number.min\u SAFE\u INTEGER)、Number.max\u SAFE\u INTEGER);
}
//返回最小值(包含)和最大值(包含)之间的随机整数
//使用Math.round()将得到非均匀分布!
函数randomInt(最小值、最大值){
var tmp,
瓦尔;
if(arguments.length==1){
最大值=最小值;
最小值=0;
}
最小值=夹紧假动作(最小值);
max=夹紧假动作(max);
如果(最小值>最大值){
tmp=min;
最小值=最大值;
max=tmp;
}
tmp=最大值-最小值+1;
if(tmp>Number.MAX\u SAFE\u整数){
tmp=新的大(最大)减(最小)加(1);
val=数学地板(tmp.次(Math.random())+min;
}否则{
val=数学地板(数学随机()*tmp)+min;
}
返回val;
}
log(randomInt(Number.MIN\u SAFE\u INTEGER,Number.MAX\u SAFE\u INTEGER))

您愿意多次调用
随机
生成一个号码吗?例如
函数bigRand(){return(randInt(0,pow(2,26))是的,如果你能告诉我如何将我的范围输入到
bigRand
中,它会给出一个均匀的分布。我如何将我的
max
min
值输入到这个中?你能告诉我如何将其用于范围而不是固定值吗?没有捕捉到这一部分。是的,这更棘手。如果你需要一致性,你不会如果你不小心的话,我们可以简单地在这些大范围内使用MOD,拒绝采样可能会很昂贵。我想…你真的致力于使用JavaScript的内部数字表示吗?使用某种基于数组的bigint,当然,在任何其他语言中,这都会更容易。:-)不完全致力于它。如果可能的话,我更愿意使用它,但如果不可能的话,那么我已经想到了一个大数字库作为一种可能的方法(尽管我仍然需要找到正确的算法来使用它,我猜这样的库不会与我正在寻找的工具一起提供)。我首先想看看我的选项/可能的解决方案是什么,如果有的话。不幸的是,Javascript是一种语言。:)Node bignum可以做到这一点,但使用OpenSLL提供加密安全的随机数,这可能超出了您的需要,但它确实存在。