在C语言中搜索生成随机数的Tuesday时,我发现this topic
当我尝试使用不带参数的rand()
函数时,我总是得到0。当我尝试使用带参数的rand()
函数时,我总是得到值41。每当我尝试使用arc4random()
和random()
函数时,我都会得到一个LNK 2019错误。
我是这么做的
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
这个代码总是生成41。我哪里做错了?我正在运行Windows XP SP3,并使用VS2010命令提示符作为编译器。
7条答案
按热度按时间vmpqdwk31#
在调用兰德初始化随机数生成器之前,应该先调用
srand()
。要么用特定的种子调用它,你总是会得到相同的伪随机序列
或调用它与一个不断变化的来源,即时间函数
响应Moon的注解rand()生成一个在0和兰德_MAX(stdlib. h中预定义的宏)之间具有相等概率的随机数
然后,您可以将此值Map到更小的范围,例如。
这对于大多数应用来说可能已经足够了,但值得指出的是,在第一种情况下,如果N不能均匀地分为
RAND_MAX+1
,则使用mod运算符会引入轻微的偏差。随机数生成器是有趣而复杂的,人们普遍认为C标准库中的rand()生成器不是一个质量很好的随机数生成器,阅读(http://en.wikipedia.org/wiki/Random_number_generation为质量的定义)。
http://en.wikipedia.org/wiki/Mersenne_twister(源代码http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html)是一个流行的高质量随机数生成器。
另外,我不知道arc4rand()或random(),所以我不能评论。
vddsk6oq2#
您需要为PRNG设置种子,以便它每次都以不同的值开始。
一个简单但低质量的种子是使用当前时间:
这将让你开始,但被认为是低质量(即。例如,如果您试图生成RSA密钥,请不要使用它)。
伪随机数生成器并不创建真正的随机数序列,而只是模拟它们。给定一个起始点数字,PRNG将始终返回相同的数字序列。默认情况下,它们以相同的内部状态开始,因此将返回相同的序列。
为了不得到相同的序列,你改变了内部状态。改变内部状态的行为称为“播种”。
vc6uscn93#
特别是作为一个初学者,你应该要求你的编译器打印每一个关于它可能生成的坏代码的警告。现代编译器知道很多不同的警告,这有助于你更好地编程。例如,当你用GNU C编译器编译这个程序时:
你在这里得到两个警告。第一个说明
rand
函数只接受零个参数,而不是像您尝试的那样只接受一个参数。要得到一个0到n
之间的随机数,可以使用表达式rand() % n
,它并不完美,但对于小的n
来说是可以的。产生的随机数通常不是均匀分布的;更频繁地返回较小的值。第二个警告告诉你你正在调用一个编译器不知道的函数。你必须告诉编译器说
#include <stdio.h>
。哪些功能需要哪些包含文件并不总是简单的,但在许多情况下,询问便携式操作系统的Open Group规范是可行的:http://www.google.com/search?q=opengroup+rand。这两个警告告诉你很多关于C编程语言的历史。40年前,函数的定义不包括参数的数量或参数的类型。调用一个未知的函数也是可以的,在大多数情况下都可以工作。如果你现在想写代码,你不应该依赖这些旧的功能,而是启用编译器的警告,理解警告,然后正确地修复它们。
d4so4syb4#
此外,线性全等PRNG倾向于在高位上产生比低位上更大的随机性,因此不要使用模来限制结果,而是使用类似于:
(This一个来自“C中的数字食谱”,第7章)
jm2pwxwz5#
你首先需要 seed 生成器,因为它不会生成 * 真实的 * 随机数!
试试这个:
fwzugrvs6#
或者,要获得范围为0到19的伪随机整数,例如,您可以像这样使用高位:
nnt7mjpx7#