【问题标题】:What does rand() do in C? [closed]rand() 在 C 中做了什么? [关闭]
【发布时间】:2015-07-29 22:14:08
【问题描述】:

rand() 在 C 中做了什么?我不使用 C++,只使用 C。 Visual Studio 2012 告诉我它的返回类型是 int __cdecl 它是 stdlib.h 的一部分 它不带任何参数。 如何设置它生成(伪)随机数的范围? 非常感谢您的回答

【问题讨论】:

  • 试试google
  • 我确实尝试过 google,但没有找到任何有用的信息。
  • 那么如何设置范围呢?
  • 我有强烈的感觉,你应该立即查阅 C 书籍。

标签: c random


【解决方案1】:

现在有一个实际问题:你不能。范围是固定的,如果你需要知道它由常量RAND_MAX定义(它是[0 .. RAND_MAX]

如果你想要一个不同的范围,你必须自己安排,通常使用 运算符 % 和可选的偏移量 ... 用于 59 之间的随机数使用

int foo = rand() % 5 + 5;

我在最近写的游戏中使用了这样的辅助函数:

int
randomNum(int min, int max)
{
    static int seeded = 0;
    if (!seeded)
    {
        seeded = 1;
        srand((unsigned int)time(0));
    }
    return (rand() % (max-min+1)) + min;
}

【讨论】:

  • 对不起,我对 c 很陌生。那么 [0..RAND_MAX] 有什么作用呢?我如何从中找出 RAND_MAX?非常感谢
  • RAND_MAXstdlib.h 中声明的常量(由您的 C 实现定义)。这意味着每个编译器都可能不同,但它通常是一个很大的值。一般来说,只需使用模数将范围转换为您需要的范围。
  • 哦...我现在明白了!非常感谢!
  • 注意:如果你需要高质量随机数,你需要在别处寻找(在Linux上可能是/dev/urandom)。
  • @immibis 确实如此。 rand() 不适用于密码学,但可以用于游戏 :)
【解决方案2】:

取决于编译器。这篇 wiki 文章包含它们的列表:linear congruential generator

如果需要扩展rand()的范围,可以多次调用,合并输出:

unsigned int r;
    /* ... */
    r  = ((rand()>>4) & 0xff)<< 0;
    r += ((rand()>>4) & 0xff)<< 8;
    r += ((rand()>>4) & 0xff)<<16;
    r += ((rand()>>4) & 0xff)<<24;

通过比较返回值来展示 rand 如何工作的示例程序。这适用于 Microsoft 编译(没有不匹配)。

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

int main(int argc, const char* argv[])
{
unsigned int seed = 1;
unsigned int rand1, rand2;
unsigned int i;

    for(i = 0; i < 20; i++){
        seed = seed*214013 + 2531011;
        rand1 = (seed >> 16) & 0x7fffu;
        rand2 = rand();
        if(rand1 != rand2)
            printf("mismatch %d %d\n", rand1, rand2);
    }
    return(0);
}

由于此版本的 rand() 仅返回 15 位种子,因此 RAND_MAX 将为 32767 或十六进制 0x7fff。如 wiki 文章中所述,周期为 2^32,这意味着种子将循环遍历所有 4,294,967,296 个可能的 32 位值,在调用 rand() 的 4,294,967,296 次调用之前永远不会重复,其中种子将循环回 1。

【讨论】:

  • 哇,感谢您是唯一一个给予我尊重的回答的人。然而,那篇维基文章并没有给我任何帮助。该库是 Windows 上的 stdlib.h。
  • 然后使用 wiki 文章中 Visual / Quick C / C++ 的行。内部种子是一个 32 位的数字,但如图所示,返回的是种子的第 30 位到第 16 位,这是一个 15 位的值。种子初始化为 1。
  • 嗯...对不起,我对这个真的很陌生,什么是种子?这告诉了我关于 RAND_MAX 的什么信息?
  • 这是一个伪随机数生成器,这意味着它不是真正随机的。从同一个种子开始,返回的序列将是相同的。这就是为什么您通常使用当前时间作为种子(或用于调试的固定值,如果您总是想要相同的“随机”数字)
猜你喜欢
  • 2020-05-23
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 2015-01-12
相关资源
最近更新 更多