Hiya, my code currently has three functions each producing a massive array of random numbers. Im wondering if there is a way of just having one function returning a linked list or multidimensional array to make it a bit neater:
(copied from 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;
}
I’m not the first to point out that you should only call
srandonce, but I’ll explain why:The more often you call
srandthe less random the output ofrandis.The
randfunction is a pseudo-random number generator. That means that it generates numbers that look random, and have mathematical properties corresponding to randomness, but they aren’t actually random. The output ofrandis actually a fixed, completely deterministic sequence of numbers.Or, rather, it produces one of a large family of completely deterministic sequences. You select which of these sequences you want by providing a “seed” value using
srand. When you givesranda seedx, the next output ofrandwill be the first number of the pseudo-random (but completely deterministic!) sequence identified by the seedx. In other words:Will return different values for different inputs, but for a given
x, will always return the same value. Not at all random!This is actually a useful feature, since if you discover a bug in a program that relies on the output of
rand, you can reliably reproduce the bug by providing the same seed tosrandin order to obtain the same sequence fromrandand so the same behavior from your program.The reason that you need to call
srandonce is because otherwise your program will always receive the same sequence of numbers fromrand(the sequence identified by seed1). The reason you do not want to callsrandmore than once (in most cases) is because you are then repeatedly forcingrandback to the beginnings of its sequences rather than letting it give you one of them in its entirety. While any given sequence has properties of randomness, the sequence of sequence-beginnings does not necessarily have this property.Obviously, it’s especially bad if you call
srandrepeatedly with the same seed, because then you’re forcingrandback to the beginning of the same sequence every time, and sorandwill always produce the same value — exactly what you don’t want.The reason you commonly see
srand(time(NULL))is because the time is likely to be different between any two invocations of a given program, which means that every time the program runs it will use a different pseudorandom sequence. Buttimeonly returns the time to the granularity of seconds, so if you do this repeatedly within a single invocation of a program, as in yours, and less than one second elapses between calls tosrand, you will be repeatedly re-seeding with the same seed, with ridiculous results, as you have observed.Bottom Line: Call
srandexactly once, before your first use ofrand. Trust that the implementers of the C library wrote a decent pseudo-random number generator, and don’t try to “increase randomness” by attempting to compensate for problems that don’t exist.