• 15
• 15
• 11
• 9
• 10

# Truly random numbers

This topic is 4477 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I need some random numbers. Right now, I'm using this code:
srand( time(NULL) );
float r = (int) filenames.size() * (rand() / ((float)RAND_MAX+1.0f));

fname = dirname + "\\" + filenames[(int)r];

And, because the number of elements in the array doesn't change, and because I'm casting to an int, I keep getting 4. (I always seem to be converting to a float to get it within a range, and then casting to an int) This is really beginning to annoy me. It seems like I can never get truly random numbers using the rand function. Does anyone know of a method, or any other functions that don't include writing 100 lines of ridiculouly math-intensive code?

##### Share on other sites
Perhaps your clock stopped ticking ? So time (NULL) = constant [grin].

Seriously, what is the value of filenames.size () ?. From what I saw, the value of filenames.size () maybe too small (around 3 or 4) so multiplying it by [0, 1) then casting back to int won't seem to change the value (if you keep it as float you'll see the changes).
You may try this little program with srand (), then mutate the 1024 value to higher or lower, you'll see what I mean:

#include "time.h"#include "stdio.h"#include "string.h"int main (){	srand( time (NULL)) ;        //If we change 1024 by 100 or 10, there'll be a very little chance the return value will be changed	float r = 1024 * rand() / ((float)RAND_MAX+1.0f) ;	char p[64] ;	sprintf (p, "%u", static_cast<int> (r)) ;        cout << p ;	return 0 ;}

You may want to multiply filenames.size () by 100 to have more significant sparse random-ed value.
Good luck.

##### Share on other sites
int r = rand()%filenames.size();
:)

##### Share on other sites
Quote:
 Original post by EndarRight now, I'm using this code:srand( time(NULL) );float r = (int) filenames.size() * (rand() / ((float)RAND_MAX+1.0f));

You're not calling srand every time are you? You should only seed the random number generator once. Otherwise it's likely your code is executing faster than the resolution of the timer, so each call to srand seeds the random number generator at exactly the same point thus giving you the same "random" number repeatedly.

Also, float r = (int) filenames.size() * (rand() / ((float)RAND_MAX+1.0f)); can probably be replaced by int r = (filenames.size() * rand()) / (RAND_MAX + 1);, which avoids the floating-point conversions. The only thing to watch out for here is that filenames.size() * RAND_MAX <= std::numeric_limits< int >::max().

Enigma

##### Share on other sites
srand( time(NULL) );// if RAND_MAX<filenames.size() you get an even but digital spreadunsigned int ui = ( filenames.size()*rand() )/RAND_MAX;// if RAND_MAX<filenames.size() you get the first RAND_MAX filesunsigned int ui = rand()%filenames.size();// this would go bang if filenames.size() is emptyfname = dirname + "\\" + filenames[ ui ];

##### Share on other sites
Stein: I tried yours, and it's working well. Thanks!

Engima: No, the srand and rand are only called once each.

Hopefully, once I get the rest working, this should go well. If not, you'll be hearing from me in this thread again.

Thanks guys!

##### Share on other sites
Quote:

Be aware that rand() has very poor randomness in its less significant bits, and operator% uses only those bits, so don't expect particularly random results.

In fact, if you only call srand() and rand() once, you're better off using
int r = time() / filenames.size();

since that requires far fewer multiplication and division operations and is just as "random."

--smw

##### Share on other sites
On the original topic title looking for truly random numbers, they may not exist. See the classic arguments about nondeterminism in the Universe.

The built-in rand function is easily predictable and may generate obvious cyclic patterns when used with operator%, depending on your seed and denominator.

Although your snippet doesn't need it, if your game uses other random numbers you might consider the boost random number generators.

boost::random:: {pick your type of generator} < ... > Generator;...Generator.seed( time(NULL) );...MyRandomNumber = Generator();

frob.