How do I get a specific range of numbers from rand

2019-01-04 01:56发布

srand(time(null));

printf("%d", rand());

Gives a high-range random number (0-32000ish), but I only need about 0-63 or 0-127, though I'm not sure how to go about it. Any help?

标签: c random
17条回答
Explosion°爆炸
2楼-- · 2019-01-04 02:26

The naive way to do it is:

int myRand = rand() % 66; // for 0-65

This will likely be a very slightly non-uniform distribution (depending on your maximum value), but it's pretty close.

To explain why it's not quite uniform, consider this very simplified example:
Suppose RAND_MAX is 4 and you want a number from 0-2. The possible values you can get are shown in this table:

rand()   |  rand() % 3
---------+------------
0        |  0
1        |  1
2        |  2
3        |  0

See the problem? If your maximum value is not an even divisor of RAND_MAX, you'll be more likely to choose small values. However, since RAND_MAX is generally 32767, the bias is likely to be small enough to get away with for most purposes.

There are various ways to get around this problem; see here for an explanation of how Java's Random handles it.

查看更多
放我归山
3楼-- · 2019-01-04 02:26

if you care about the quality of your random numbers don't use rand()

use some other prng like http://en.wikipedia.org/wiki/Mersenne_twister or one of the other high quality prng's out there

then just go with the modulus.

查看更多
再贱就再见
4楼-- · 2019-01-04 02:28

If you don't overly care about the 'randomness' of the low-order bits, just rand() % HI_VAL.

Also:

(double)rand() / (double)RAND_MAX;  // lazy way to get [0.0, 1.0)
查看更多
别忘想泡老子
5楼-- · 2019-01-04 02:28
2 cents (ok 4 cents):

n = rand()
x = result
l = limit

n/RAND_MAX = x/l

Refactor:

(l/1)*(n/RAND_MAX) = (x/l)*(l/1)

Gives:

x = l*n/RAND_MAX

int randn(int limit)

{

    return limit*rand()/RAND_MAX;

}

int i;

for (i = 0; i < 100; i++) { 

    printf("%d ", randn(10)); 
    if (!(i % 16)) printf("\n"); 

}

> test
0
5 1 8 5 4 3 8 8 7 1 8 7 5 3 0 0
3 1 1 9 4 1 0 0 3 5 5 6 6 1 6 4
3 0 6 7 8 5 3 8 7 9 9 5 1 4 2 8
2 7 8 9 9 6 3 2 2 8 0 3 0 6 0 0
9 2 2 5 6 8 7 4 2 7 4 4 9 7 1 5
3 7 6 5 3 1 2 4 8 5 9 7 3 1 6 4
0 6 5
查看更多
趁早两清
6楼-- · 2019-01-04 02:29

Just to add some extra detail to the existing answers.

The mod % operation will always perform a complete division and therefore yield a remainder less than the divisor.

x % y = x - (y * floor((x/y)))

An example of a random range finding function with comments:

uint32_t rand_range(uint32_t n, uint32_t m) {
    // size of range, inclusive
    const uint32_t length_of_range = m - n + 1;

    // add n so that we don't return a number below our range
    return (uint32_t)(rand() % length_of_range + n);
}

Another interesting property as per the above:

x % y = x, if x < y

const uint32_t value = rand_range(1, RAND_MAX); // results in rand() % RAND_MAX + 1
// TRUE for all x = RAND_MAX, where x is the result of rand()
assert(value == RAND_MAX);
result of rand()
查看更多
神经病院院长
7楼-- · 2019-01-04 02:30

rand() will return numbers between 0 and RAND_MAX, which is at least 32767.

If you want to get a number within a range, you can just use modulo.

int value = rand() % 66; // 0-65

For more accuracy, check out this article. It discusses why modulo is not necessarily good (bad distributions, particularly on the high end), and provides various options.

查看更多
登录 后发表回答