Generate random numbers uniformly over an entire range

后端 未结 17 2306
野性不改
野性不改 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 04:52

    This should provide a uniform distribution over the range [low, high) without using floats, as long as the overall range is less than RAND_MAX.

    uint32_t rand_range_low(uint32_t low, uint32_t high)
    {
        uint32_t val;
        // only for 0 < range <= RAND_MAX
        assert(low < high);
        assert(high - low <= RAND_MAX);
    
        uint32_t range = high-low;
        uint32_t scale = RAND_MAX/range;
        do {
            val = rand();
        } while (val >= scale * range); // since scale is truncated, pick a new val until it's lower than scale*range
        return val/scale + low;
    }
    

    and for values greater than RAND_MAX you want something like

    uint32_t rand_range(uint32_t low, uint32_t high)
    {
        assert(high>low);
        uint32_t val;
        uint32_t range = high-low;
        if (range < RAND_MAX)
            return rand_range_low(low, high);
        uint32_t scale = range/RAND_MAX;
        do {
            val = rand() + rand_range(0, scale) * RAND_MAX; // scale the initial range in RAND_MAX steps, then add an offset to get a uniform interval
        } while (val >= range);
        return val + low;
    }
    

    This is roughly how std::uniform_int_distribution does things.

提交回复
热议问题