如何使用rand函数在特定范围内生成数字?

Mr.*_*ork 5 c random function

我想在特定范围内制作随机数,例如"选择18到35之间的随机数"?我怎么能用这个rand()功能做到这一点?

Nea*_*alB 13

根据您使用的语言,内置随机数生成器可能已具备此功能 - 进行更多研究.

假设您随机数生成器始终返回某个给定范围内的数字.仅仅为了争论,我们可以说范围是0..65536,但是你想要在你的例子中Low..High,18..35范围内的随机数.

做错的方法是这样的:

 r = (rand() % (High - Low + 1)) + Low
Run Code Online (Sandbox Code Playgroud)

rand()返回0..65536范围内的数字.除以(高 - 低+ 1)后的余数,在本例中为(35 - 18 + 1 = 18).结果是0..17之间的数字.为此你添加低(18),将结果r移动到18..35的范围内.您正在寻找的范围.

在用于获得余数的除数不是rand()函数返回的上限的偶数倍的情况下,以这种方式生成的数字不具有均匀分布.请参阅Fischer Yates算法 - 模数偏差.要消除此偏差,您需要计算小于rand()返回的最大数字,但均匀地除以(High - Low + 1).在你的情况下是3640*18 = 65520.使用它作为rand()返回的数字的高范围过滤器,如下所示:

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

现在,您生成的随机数应具有与rand()相同的分布特征.


cdh*_*wie 6

如果这是用C语言编写的,那么你就非常接近了.编译此代码:

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

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

在管道中运行它会产生以下输出:

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
Run Code Online (Sandbox Code Playgroud)

关键是你忘了添加1 - fencepost错误.

您可以将其概括为一个函数:

int random_between(int min, int max) {
    return rand() % (max - min + 1) + min;
}
Run Code Online (Sandbox Code Playgroud)

  • 该技术引入了分布偏置,其中除数不是MAX_RAND的偶数倍. (4认同)