【问题标题】:How to use the rand function to make numbers in a specific range?如何使用 rand 函数生成特定范围内的数字?
【发布时间】:2011-05-15 07:09:16
【问题描述】:

我想在特定范围内生成随机数,例如“选择 18 到 35 之间的随机数”?如何使用rand() 函数做到这一点?

【问题讨论】:

  • iv 尝试了 rand%(35-18)+18,我现在知道它会产生错误
  • 你使用什么语言?
  • 我不明白你在用 (35-18)+18 做什么。那不是只有35吗? o__O
  • @townsean:% 运算符的优先级高于 + 运算符。所以读为(rand() % (35 - 18)) + 18。这种方法适用于 rand() 可以返回任意大数字的环境,但当 rand() 返回大于或等于 0 但小于 1 的数字时,它将始终返回 18。
  • 我正在为人们生成一个随机年龄,年龄必须在 18-35 之间,这些人的名字是从 tex 文件中读取的,我已经完成了所有这些,现在我需要我添加的年龄正确我也尝试过 p->age=rand()%10+25 并且所有年龄都在 18-35 之间但最低年龄是 25 所以它真的不是 rand b/w 18- 35

标签: c function random


【解决方案1】:

根据您使用的语言,内置的随机数生成器可能 已经具备这种能力 - 做更多的研究。

假设你的随机数生成器总是返回数字 在某个给定的范围内。只是为了争论,假设范围是 0..65536 但是 在您的示例中,您需要 Low..High, 18..35 范围内的随机数。

错误的做法是这样的:

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

rand() 返回一个 0..65536 范围内的数字。除以后取余数 (High - Low + 1) 在本例中为 (35 - 18 + 1 = 18)。结果是一个介于 0..17.为此,您添加 Low (18),它将结果 r 移动到 18..35 范围内。范围 你正在寻找。

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

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

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

【讨论】:

    【解决方案2】:

    如果这是用 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);
        }
    }
    

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

    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
    

    关键是你忘了加1——the fencepost error

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

    int random_between(int min, int max) {
        return rand() % (max - min + 1) + min;
    }
    

    【讨论】:

    • 这种技术引入了分布偏差,其中除数不是 MAX_RAND 的偶数倍。
    • @NealB:是的,我想提一下。不过,修复并非易事,对于完美分布不是什么大问题的测试数据,不值得付出努力。
    • 关于模偏差的问题,请参阅stackoverflow.com/questions/10984974/…
    【解决方案3】:
    1. 您只需要整数吗?
    2. 您想要均匀分布吗?
    3. 是否要将 18 和 35 作为可能的值包含在内?
    4. 您希望使用哪种语言?

    一般来说,如果 rand() 返回 [0.0 ... 1.0) 中的浮点值 (也就是说,您可能会得到任意接近 1.0 但实际上不是 1 的值) 那么你会想要类似的东西

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

    请注意,这永远不会真正返回 hi 值 - 因此我有 将其增加 1(即,您将获得从 18 到 35 的所有值,但绝不会是 36)。

    希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      假设 rand() 给你一个介于 0 和 1.0 之间的数字

      然后使用 rand() * (35 - 18) + 18 得到一个介于 18 和 35 之间的随机数。

      编辑:你不需要这个模组。

      【讨论】:

      • rand() 在 C 中返回 int,它不是浮点类型。 rand() 的文档表明它返回一个介于 0 和 RAND_MAX 之间的整数。
      • ?谁告诉你它是 C。Java Math.random() 给出 0 到 1 之间的随机数。
      猜你喜欢
      • 2011-12-22
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      相关资源
      最近更新 更多