【发布时间】:2015-07-29 22:14:08
【问题描述】:
rand() 在 C 中做了什么?我不使用 C++,只使用 C。 Visual Studio 2012 告诉我它的返回类型是 int __cdecl 它是 stdlib.h 的一部分 它不带任何参数。 如何设置它生成(伪)随机数的范围? 非常感谢您的回答
【问题讨论】:
rand() 在 C 中做了什么?我不使用 C++,只使用 C。 Visual Studio 2012 告诉我它的返回类型是 int __cdecl 它是 stdlib.h 的一部分 它不带任何参数。 如何设置它生成(伪)随机数的范围? 非常感谢您的回答
【问题讨论】:
现在有一个实际问题:你不能。范围是固定的,如果你需要知道它由常量RAND_MAX定义(它是[0 .. RAND_MAX])
如果你想要一个不同的范围,你必须自己安排,通常使用 模 运算符 % 和可选的偏移量 ... 用于 5 和 9 之间的随机数使用
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;
}
【讨论】:
RAND_MAX 是stdlib.h 中声明的常量(由您的 C 实现定义)。这意味着每个编译器都可能不同,但它通常是一个很大的值。一般来说,只需使用模数将范围转换为您需要的范围。
rand() 不适用于密码学,但可以用于游戏 :)
取决于编译器。这篇 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。
【讨论】: