Javascript中的无偏随机范围生成器

时间:2013-03-24 01:59:21

标签: javascript random numbers range generator

为了防止 max 的偏差,我每次小数范围都高于 max 时重新计算,而不是删除小数。使用 random()会引入一些偏见,但我认为这是可以接受的。

可选arg 十进制是一个整数,表示要包含的小数位数。

可选的arg exclude 可以方便地从结果中排除特定数字(通常为0)。

如果省略所有参数,则可以选择性地随机返回true或false。

基本上,我只是想知道是否有任何方法可以在不增加偏差(甚至减少偏差)的情况下提高速度和效率。似乎while循环可能会减慢速度。我正在将它用于动画,并且不希望有偏差的结果(特别是在1.0到2.0之间的小范围内)。

function random(min, max, decimal, exclude) {
    if (min == null) return (Math.random()*2 >= 1) ? true : false
    var decimal = (decimal == null) ? 1 : Math.pow(10,decimal), result = exclude
    while (result == exclude) {
        result = max+1
        while (result > max) var result = Math.round((Math.random()*(max-min+1)+min)*decimal)/decimal
    }
    return result
}

2 个答案:

答案 0 :(得分:1)

分布是均匀的,因此如果数字超出范围,则可以不进行重复,而是可以缩放/移动伪随机数。

var rand = Math.random() * (max - min) + min;

这会删除你的一个while循环,并且应该加速代码。

答案 1 :(得分:1)

这是一个更清洁的实现:

function random(min, max, decimal, exclude) {
    // if no min and max is passed, return true or false
    if (arguments.length < 2) return(Math.random() >= 0.5);

    // calc decimal multiplier
    var factor = 1, result;
    if (typeof decimal === "number") {
        factor = Math.pow(10, decimal);
    }

    // loop until we get a value that isn't our exclude value
    do {
        // calc rand value in proper range
        result = Math.random() * (max - min) + min;

        // adjust to proper number of decimal digits
        result = Math.round(result * factor) / factor;
    } while (result === exclude);
    return result;
}

带小数的工作演示:http://jsfiddle.net/jfriend00/SjgaW/

将演示工作为整数(带排除值):http://jsfiddle.net/jfriend00/GgkJv/

的变化:

  1. decimal局部变量更改为与参数名称不同,以便参数可以正常工作
  2. 使用适当的范围缩放删除一个while循环
  3. 更改为do / while因此在计算之前不会测试条件
  4. 使用===来避免类型转换
  5. 从真/假计算中删除乘法和三元运算符,因为比较已经返回true / false
  6. 更明确地检查不需要传递的参数或依赖类型转换到null
  7. 添加相关评论