Generate random numbers uniformly over an entire range

后端 未结 17 2315
野性不改
野性不改 2020-11-22 04:21

I need to generate random numbers within a specified interval, [max;min].

Also, the random numbers should be uniformly distributed over the interval, not located to

相关标签:
17条回答
  • 2020-11-22 05:03

    You should look at RAND_MAX for your particular compiler/environment. I think you would see these results if rand() is producing a random 16-bit number. (you seem to be assuming it will be a 32-bit number).

    I can't promise this is the answer, but please post your value of RAND_MAX, and a little more detail on your environment.

    0 讨论(0)
  • 2020-11-22 05:03

    By their nature, a small sample of random numbers doesn't have to be uniformly distributed. They're random, after all. I agree that if a random number generator is generating numbers that consistently appear to be grouped, then there is probably something wrong with it.

    But keep in mind that randomness isn't necessarily uniform.

    Edit: I added "small sample" to clarify.

    0 讨论(0)
  • 2020-11-22 05:05

    Check what RAND_MAX is on your system -- I'm guessing it is only 16 bits, and your range is too big for it.

    Beyond that see this discussion on: Generating Random Integers within a Desired Range and the notes on using (or not) the C rand() function.

    0 讨论(0)
  • 2020-11-22 05:05

    If you want numbers to be uniformly distributed over the range, you should break your range up into a number of equal sections that represent the number of points you need. Then get a random number with a min/max for each section.

    As another note, you should probably not use rand() as it's not very good at actually generating random numbers. I don't know what platform you're running on, but there is probably a better function you can call like random().

    0 讨论(0)
  • 2020-11-22 05:06

    This is the solution I came up with:

    #include "<stdlib.h>"
    
    int32_t RandomRange(int32_t min, int32_t max) {
        return (rand() * (max - min + 1) / (RAND_MAX + 1)) + min;
    }
    

    This is a bucket solution, conceptually similar to the solutions that use rand() / RAND_MAX to get a floating point range between 0-1 and then round that into a bucket. However, it uses purely integer math, and takes advantage of integer division flooring to round down the value to the nearest bucket.

    It makes a few assumptions. First, it assumes that RAND_MAX * (max - min + 1) will always fit within an int32_t. If RAND_MAX is 32767 and 32 bit int calculations are used, the the maximum range you can have is 32767. If your implementation has a much larger RAND_MAX, you can overcome this by using a larger integer (like int64_t) for the calculation. Secondly, if int64_t is used but RAND_MAX is still 32767, at ranges greater than RAND_MAX you will start to get "holes" in the possible output numbers. This is probably the biggest issue with any solution derived from scaling rand().

    Testing over a huge number of iterations nevertheless shows this method to be very uniform for small ranges. However, it is possible (and likely) that mathematically this has some small bias and possibly develops issues when the range approaches RAND_MAX. Test it for yourself and decide if it meets your needs.

    0 讨论(0)
  • 2020-11-22 05:10

    If you are able to, use Boost. I have had good luck with their random library.

    uniform_int should do what you want.

    0 讨论(0)
提交回复
热议问题