这是我第一次用C语言尝试随机数(我想念C#).这是我的代码:
int i, j = 0;
for(i = 0; i <= 10; i++) {
j = rand();
printf("j = %d\n", j);
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,每次运行代码时都会得到相同的序列.但是如果我srand(/*somevalue/*)在for循环之前添加,它会生成不同的随机序列.有谁能解释为什么?
kjf*_*tch 85
你必须播种它.随着时间播种它是一个好主意:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ()
{
srand ( time(NULL) );
printf ("Random Number: %d\n", rand() %100);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您获得相同的序列,因为rand()如果您不调用,则自动播种值为1 srand().
由于评论
rand()将返回介于0和RAND_MAX(在标准库中定义)之间的数字.使用模运算符(%)给出除法的余数rand() / 100.这将强制随机数在0-99范围内.例如,要获得0-999范围内的随机数,我们将适用rand() % 1000.
nos*_*nos 34
rand()返回伪随机数.它根据给定的算法生成数字.该算法的起点始终相同,因此您将看到为每次调用生成的相同序列.当您需要验证程序的行为和一致性时,这很方便.
您可以使用srand函数设置随机生成器的"种子" (仅在程序中调用一次srand)从rand()生成器获取不同序列的一种常用方法是将种子设置为当前时间或id过程:
函数srand(时间(NULL)); 或者srand(getpid()); 在计划开始时.
对于计算机来说,生成真正的随机性非常困难,但是对于实际的非加密相关工作,尝试均匀分布生成的序列的算法工作正常.
caf*_*caf 11
这里有很多答案,但似乎没有人真正解释为什么rand()总是在给定相同种子的情况下生成相同的序列 - 甚至是种子真正做的事情.所以这里.
rand()函数保持内部状态.从概念上讲,您可以将其视为某种类型的全局变量rand_state.每次调用rand()时,它都会执行两项操作.它使用现有状态来计算新状态,并使用新状态计算要返回给您的数字:
state_t rand_state = INITIAL_STATE;
state_t calculate_next_state(state_t s);
int calculate_return_value(state_t s);
int rand(void)
{
rand_state = calculate_next_state(rand_state);
return calculate_return_value(rand_state);
}
Run Code Online (Sandbox Code Playgroud)
现在你可以看到,每次调用rand()时,它都会使rand_state沿着预先确定的路径向前移动一步.您看到的随机值仅基于您沿着该路径的位置,因此它们也将遵循预先确定的顺序.
现在这里是srand()的用武之地.它可以让你跳到路径上的另一个点:
state_t generate_random_state(unsigned int seed);
void srand(unsigned int seed)
{
rand_state = generate_random_state(seed);
}
Run Code Online (Sandbox Code Playgroud)
state_t,calculate_next_state(),calculate_return_value()和generate_random_state()的确切细节可能因平台而异,但它们通常非常简单.
您可以从中看到,每次程序启动时,rand_state将从INITIAL_STATE开始(相当于generate_random_state(1)) - 这就是为什么如果不使用srand(),总是得到相同的序列.
小智 9
如果我记得Knuth在随机数生成章节开头的开创性着作"计算机编程艺术"的引用,它是这样的:
"从技术上讲,任何试图通过数学方法产生随机数的人都处于犯罪状态".
简单地说,股票随机数生成器是算法,数学和100%可预测.在许多情况下,这实际上是一件好事,其中需要可重复的"随机"数字序列 - 例如对于某些统计练习,您不希望结果中的"摆动"真正随机数据引入,这要归功于聚类效应.
虽然从计算机的硬件中获取"随机"数据是一种流行的第二种选择,但它并不是真正随机的 - 尽管操作环境越复杂,随机性的可能性就越大 - 或者至少是不可预测性.
真正随机的数据生成器倾向于寻找外部资源.放射性衰变是最受欢迎的,类星体的行为也是如此.任何根源于量子效应的东西都是随机的 - 这对爱因斯坦的烦恼很大.
随机数生成器实际上并不是随机的,它们像大多数软件一样是完全可预测的.rand做的是每次调用一个看起来是随机的伪随机数.为了正确使用它,你需要给它一个不同的起点.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ()
{
/* initialize random seed: */
srand ( time(NULL) );
printf("random number %d\n",rand());
printf("random number %d\n",rand());
printf("random number %d\n",rand());
printf("random number %d\n",rand());
return 0;
}
Run Code Online (Sandbox Code Playgroud)