(从http://pastebin.com/Y5aE6XKS复制)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#ifndef RAND_MAX
#define RAND_MAX 2147483648
#endif
#define N 420000
double* rdm_X(void);
double* rdm_Y(void);
double* rdm_Z(void);
void main(void)
{
double* Random_number_list_X = rdm_X();
double* Random_number_list_Y = rdm_Y();
double* Random_number_list_Z = rdm_Z();
double X[N+1], Y[N+1], Z[N+1], density = 1, vol = 42.0;
double sum = 0, sum_x = 0, sum_y = 0, sum_z = 0;
int i;
for (i = 0; i <= N; i++) {
X[i] = 3 * Random_number_list_X[i] + 1;
Y[i] = 7 * Random_number_list_Y[i] - 3;
Z[i] = 2 * Random_number_list_Z[i] - 1;
if ((Z[i]*Z[i]) + (sqrt(X[i]*X[i] + Y[i]*Y[i]) - 3)*(sqrt(X[i]*X[i] + Y[i]*Y[i]) - 3) <= 1) {
sum += density;
sum_x += X[i] * density;
sum_y += Y[i] * density;
sum_z += Z[i] * density;
}
}
printf("(%.5lf, %.5lf, %.5lf)\n",
sum_x/sum, sum_y/sum, sum_z/sum);
}
double* rdm_X(void)
{
double* Random_number_list_X = calloc(N + 1, sizeof(double));
int i;
srand(time(NULL));
for (i = 1; i <= N; i++) {
Random_number_list_X[i] = (float) rand() / (float) RAND_MAX;
}
return Random_number_list_X;
}
double* rdm_Y(void)
{
double* Random_number_list_Y = calloc(N + 1, sizeof(double));
int i;
sleep(1);
srand(time(NULL));
for (i = 1; i <= N; i++) {
Random_number_list_Y[i] = (float) rand() / (float) RAND_MAX;
}
return Random_number_list_Y;
}
double* rdm_Z(void)
{
double* Random_number_list_Z = calloc(N + 1, sizeof(double));
int i;
sleep(2);
srand(time(NULL));
for (i = 1; i <= N; i++) {
Random_number_list_Z[i] = (float) rand() / (float) RAND_MAX;
}
return Random_number_list_Z;
}
答案 0 :(得分:6)
几点:
RAND_MAX
。main
返回一个int。srand
一次。srand
的额外调用,并使用一个函数初始化阵列。答案 1 :(得分:4)
我不是第一个指出你应该只调用srand
一次的人,但我会解释为什么:
srand
的输出越频繁地rand
less 随机调用。
rand
函数是伪 - 随机数生成器。这意味着它生成看起来随机的数字,并且具有与随机性相对应的数学属性,但它们实际上并不是随机的。 rand
的输出实际上是一个固定的,完全确定的数字序列。
或者,它产生了一大类完全确定性序列中的一个。您可以使用srand
提供“种子”值来选择所需的序列中的哪一个。当您为srand
提供种子x
时,rand
的下一个输出将是种子{{1}标识的伪随机(但完全确定的!)序列的第一个数字}。换句话说:
x
将为不同的输入返回不同的值,但对于给定的int foo(int x)
{
srand(x);
return rand();
}
,将始终返回相同的值。一点也不随便!
这实际上是一个有用的功能,因为如果您发现某个程序中的错误依赖于x
的输出,您可以通过向rand
提供相同的种子来可靠地重现该错误从srand
获取相同的序列,从而使你的程序具有相同的行为。
您需要拨打rand
一次的原因是因为否则您的程序将始终从srand
(由种子rand
标识的序列)接收相同的数字序列。你不想要多次调用1
的原因(在大多数情况下)是因为你反复强迫srand
回到序列的开头而不是让它它给你一个完整的。虽然任何给定序列都具有随机性,但序列开始序列不一定具有此属性。
显然,如果你使用相同的种子反复调用rand
,那么尤其不好,因为那样你就迫使srand
回到了每次开始相同的序列,因此rand
将始终生成相同的值 - 正是您不想要的。
您经常看到rand
的原因是因为给定程序的任何两次调用之间的时间可能不同,这意味着每次程序运行时它将使用不同的伪随机序列。但是srand(time(NULL))
只返回粒度为秒的时间,所以如果你在一个程序的单次调用中重复这样做,就像在你的程序中一样,并且在调用time
之间不到一秒钟,你正如你所观察到的那样,将会用同样的种子反复播种,结果非常荒谬。
底线:在您第一次使用srand
之前,只需拨打srand
一次。相信C库的实现者编写了一个体面的伪随机数生成器,并且不试图通过尝试补偿不存在的问题来“增加随机性”。
答案 2 :(得分:1)
您的三个功能之间的唯一区别是他们如何调用sleep()
。当然你可以把所有三个都折叠成一个函数,并在一个循环中调用它三次?
答案 3 :(得分:1)
每次程序调用只能调用srand()
一次,通常在main()
内。
int main(void) {
/* initializations */
srand(time(NULL));
/* rest of program, with no more calls to srand() */
}
答案 4 :(得分:1)
其他人已经解决了您的程序的一些问题,但是您是否意识到每次运行它时泄漏超过10兆字节的内存?自由()...