Generating random integer from a range

前端 未结 13 1522
失恋的感觉
失恋的感觉 2020-11-22 03:12

I need a function which would generate a random integer in given range (including border values). I don\'t unreasonable quality/randomness requirements, I have four requirem

13条回答
  •  鱼传尺愫
    2020-11-22 03:58

    In this thread rejection sampling was already discussed, but I wanted to suggest one optimization based on the fact that rand() % 2^something does not introduce any bias as already mentioned above.

    The algorithm is really simple:

    • calculate the smallest power of 2 greater than the interval length
    • randomize one number in that "new" interval
    • return that number if it is less than the length of the original interval
      • reject otherwise

    Here's my sample code:

    int randInInterval(int min, int max) {
        int intervalLen = max - min + 1;
        //now calculate the smallest power of 2 that is >= than `intervalLen`
        int ceilingPowerOf2 = pow(2, ceil(log2(intervalLen)));
    
        int randomNumber = rand() % ceilingPowerOf2; //this is "as uniform as rand()"
    
        if (randomNumber < intervalLen)
            return min + randomNumber;      //ok!
        return randInInterval(min, max);    //reject sample and try again
    } 
    

    This works well especially for small intervals, because the power of 2 will be "nearer" to the real interval length, and so the number of misses will be smaller.

    PS
    Obviously avoiding the recursion would be more efficient (no need to calculate over and over the log ceiling..) but I thought it was more readable for this example.

提交回复
热议问题