How to use the rand function to make numbers in a

2019-01-08 01:51发布

I would like to make random numbers in a specific range, like "pick a random number between 18 and 35"? How can I do that with the rand() function?

4条回答
劫难
2楼-- · 2019-01-08 02:13
  1. Do you want integers-only?
  2. Do you want a uniform distribution?
  3. Do you want to include both 18 and 35 as possible values?
  4. What language would you prefer to use?

in general, if rand() returns a float value in [0.0 ... 1.0) (that is, you may get values arbitrarily close to 1.0 but not actually 1) then you will want something like

hi = 36
lo = 18
res = int( (hi-lo)*rand() + lo ) # returns random values in 18..35

Note that this will never actually return the hi value - therefore I have incremented it by 1 (ie, you will get all values from 18 to 35 inclusive, but never 36).

Hope that helps.

查看更多
淡お忘
3楼-- · 2019-01-08 02:18

Depending on the language you are using, the built in Random number generator may already have this capability - do a bit more research.

Suppose that the random number generator that you have always returns numbers in some given range. Just for the sake of argument, lets say the range is 0..65536 but you want random numbers in the range Low..High, 18..35 in your example.

The wrong way to do it would be something like:

 r = (rand() % (High - Low + 1)) + Low

rand() returns a number in range 0..65536. Take the remainder after dividing by (High - Low + 1) which in this example is (35 - 18 + 1 = 18). The result is a number between 0..17. To this you add Low (18) which shifts the result, r, into the range 18..35. The range you are looking for.

Numbers generated this way do not have a uniform distribution in cases where the divisor used to obtain the remainder is not an even multiple of the upper limit returned by the rand() function. See the Fischer Yates Algorithm - Modulo Bias. To remove this bias you need to calculate the largest number that is smaller than what rand() returns but evenly divides by (High - Low + 1). In your case that is 3640 * 18 = 65520. Use this as a high range filter on the numbers returned by rand() as follows:

  do forever {
     r = rand()
     if r <= 65520 then {
         r = (r % (High - Low + 1)) + Low
         break
         }
     } 

Now the random numbers you generate should have the same distribution characteristics as rand().

查看更多
老娘就宠你
4楼-- · 2019-01-08 02:37

If this is written in C, then you are pretty close. Compiling this code:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i;
    for (i = 0; i < 1000000; i++) {
        printf("%d\n", rand()%(35-18+1)+18);
    }
}

And running it in a pipeline produces this output:

chris@zack:~$ gcc -o test test.c
chris@zack:~$ ./test | sort | uniq -c
  55470 18
  55334 19
  55663 20
  55463 21
  55818 22
  55564 23
  55322 24
  55886 25
  55947 26
  55554 27
  55342 28
  55526 29
  55719 30
  55435 31
  55669 32
  55818 33
  55205 34
  55265 35

The key is you forgot to add 1 -- the fencepost error.

You can generalize this into a function:

int random_between(int min, int max) {
    return rand() % (max - min + 1) + min;
}
查看更多
该账号已被封号
5楼-- · 2019-01-08 02:40

assume rand() give you a number between 0 and 1.0

then use rand() * (35 - 18) + 18 to get a random number between 18 and 35.

Edit: you don't need mod for this.

查看更多
登录 后发表回答