So, I'm trying to create a random vector (think geometry, not an expandable array), and every time I call my random vector function I get the same x value, though y and z are different.
int main () {
srand ( (unsigned)time(NULL));
Vector<double> a;
a.randvec();
cout << a << endl;
return 0;
}
using the function
//random Vector
template <class T>
void Vector<T>::randvec()
{
const int min=-10, max=10;
int randx, randy, randz;
const int bucket_size = RAND_MAX/(max-min);
do randx = (rand()/bucket_size)+min;
while (randx <= min && randx >= max);
x = randx;
do randy = (rand()/bucket_size)+min;
while (randy <= min && randy >= max);
y = randy;
do randz = (rand()/bucket_size)+min;
while (randz <= min && randz >= max);
z = randz;
}
For some reason, randx will consistently return 8, whereas the other numbers seem to be following the (pseudo) randomness perfectly. However, if I put the call to define, say, randy before randx, randy will always return 8.
Why is my first random number always 8? Am I seeding incorrectly?
A simple quickfix is to call
rand
a few times after seeding.Just to explain better, the first call to rand() in four sequential runs of a test program gave the following output:
Notice how similar they are? For example, if you divide
rand()
by 100, you will get the same number 3 times in a row. Now take a look at the second result of rand() in four sequential runs:This looks much better, doesn't it? I really don't see any reason for the downvotes.
Your implementation, through integer division, ignores the smallest 4-5 bit of the random number. Since your RNG is seeded with the system time, the first value you get out of it will change only (on average) every 20 seconds.
This should work:
where
is a random double value in [0, 1) and the rest is just shifting it around.
Also to mention, you can even get rid of that strange
bucket_size
variable and use the following method to generate numbers froma
tob
inclusively:I had the same problem exactly. I fixed it by moving the srand() call so it was only called once in my program (previously I had been seeding it at the top of a function call). Don't really understand the technicalities - but it was problem solved.
I don't see any problem with your
srand()
, and when I tried running extremely similar code, I did not repeatedly get the same number with the firstrand()
. However, I did notice another possible issue.This line probably does not do what you intended. As long as
min < max
(and it always should be), it's impossible forrandx
to be both less than or equal tomin
and greater than or equal tomax
. Plus, you don't need to loop at all. Instead, you can get a value in between min and max using:The issue is that the random number generator is being seeded with a values that are very close together - each run of the program only changes the return value of time() by a small amount - maybe 1 second, maybe even none! The rather poor standard random number generator then uses these similar seed values to generate apparently identical initial random numbers. Basically, you need a better initial seed generator than time() and a better random number generator than rand().
The actual looping algorithm used is I think lifted from Accelerated C++ and is intended to produce a better spread of numbers over the required range than say using the mod operator would. But it can't compensate for always being (effectively) given the same seed.