在搜索有关在C中生成随机数的教程时,我找到了this topic
当我尝试使用没有参数的rand()
函数时,我总是得到0.当我尝试使用带参数的rand()
函数时,我总是得到值41.每当我尝试使用arc4random()
和random()
函数,我收到LNK2019错误。
这就是我所做的:
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
此代码始终生成41.我哪里错了?我正在运行Windows XP SP3并使用VS2010命令提示符作为编译器。
答案 0 :(得分:31)
你应该在调用rand之前调用srand()来初始化随机数生成器。
使用特定种子调用它,您将始终获得相同的伪随机序列
#include <stdlib.h>
int main ()
{
srand ( 123 );
int random_number = rand();
return 0;
}
或使用不断变化的来源,即时间函数
来调用它#include <stdlib.h>
#include <time.h>
int main ()
{
srand ( time(NULL) );
int random_number = rand();
return 0;
}
回应Moon的评论 rand()生成一个随机数,其概率介于0和RAND_MAX之间(在stdlib.h中预先定义的宏)
然后,您可以将此值映射到较小的范围,例如
int random_value = rand(); //between 0 and RAND_MAX
//you can mod the result
int N = 33;
int rand_capped = random_value % N; //between 0 and 32
int S = 50;
int rand_range = rand_capped + S; //between 50 and 82
//you can convert it to a float
float unit_random = random_value / (float) RAND_MAX; //between 0 and 1 (floating point)
这对于大多数用途来说可能就足够了,但是值得注意的是,在第一种情况下,如果N没有均匀地划分为RAND_MAX + 1,则使用mod运算符会引入轻微的偏差。
随机数生成器很有趣且复杂,人们普遍认为C标准库中的rand()生成器不是一个高质量的随机数生成器,读取(http://en.wikipedia.org/wiki/Random_number_generation用于定义质量)。 / p>
http://en.wikipedia.org/wiki/Mersenne_twister(来源http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html)是一种流行的高质量随机数生成器。
另外,我不知道arc4rand()或random()所以我无法评论。
答案 1 :(得分:5)
您需要为您的PRNG播种,以便每次都以不同的值开始。
简单但低质量种子是使用当前时间:
srand(time(0));
这会让你开始,但被认为是低质量(例如,如果你试图生成RSA密钥,请不要使用它。)
背景。伪随机数生成器不会创建真正的随机数序列,只是模拟它们。给定起始点编号,PRNG将始终返回相同的数字序列。默认情况下,它们以相同的内部状态开始,因此将返回相同的序列。
要获得相同的序列,请更改内部状态。改变内部状态的行为称为“播种”。
答案 2 :(得分:3)
#include <stdlib.h>
int main()
{
int x;
x = rand(6);
printf("%d", x);
}
特别是作为初学者,您应该让编译器打印关于它可以生成的错误代码的每个警告。现代编译器知道许多不同的警告,可以帮助您更好地编程。例如,当您使用GNU C编译器编译此程序时:
$ gcc -W -Wall rand.c
rand.c: In function `main':
rand.c:5: error: too many arguments to function `rand'
rand.c:6: warning: implicit declaration of function `printf'
这里有两个警告。第一个说rand
函数只接受零参数,而不是你尝试过的参数。要获得介于0和n
之间的随机数,您可以使用表达式rand() % n
,这对于小n
来说并不完美。得到的随机数通常不均匀分布;较小的值会更频繁地返回。
第二个警告告诉您正在调用编译器当时不知道的函数。你必须通过说#include <stdio.h>
来告诉编译器。哪些函数并不总是很简单需要哪些包含文件,但在许多情况下要求Open Group规范提供便携式操作系统:http://www.google.com/search?q=opengroup+rand。
这两个警告告诉你很多关于C编程语言的历史。 40年前,函数的定义不包括参数的数量或参数的类型。调用一个未知函数也是可以的,这在大多数情况下都有效。如果你想今天编写代码,你不应该依赖这些旧功能,而是启用编译器的警告,理解警告,然后正确修复它们。
答案 3 :(得分:3)
此外,线性同余PRNG倾向于在较低位上的较高位上产生更多随机性,因此限制结果不使用模数,而是使用类似的东西:
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
(这个来自“C中的数字食谱”,第7章)
答案 4 :(得分:1)
首先需要种子生成器,因为它不会生成真正的随机数!
试试这个:
#include <stdlib.h>
#include <time.h>
int main()
{
// random seed, time!
srand( time(NULL) ); // hackish but gets the job done.
int x;
x = rand(); // everytime it is different because the seed is different.
printf("%d", x);
}
答案 5 :(得分:1)
或者,要获得0到19范围内的伪随机int, 例如,你可以使用这样的高位:
j = ((rand() >> 15) % 20;
答案 6 :(得分:1)
int *generate_randomnumbers(int start, int end){
int *res = malloc(sizeof(int)*(end-start));
srand(time(NULL));
for (int i= 0; i < (end -start)+1; i++){
int r = rand()%end + start;
int dup = 0;
for (int j = 0; j < (end -start)+1; j++){
if (res[j] == r){
i--;
dup = 1;
break;
}
}
if (!dup)
res[i] = r;
}
return res;
}