PDA

View Full Version : Stupid Problems With rand()


Douglas O'Brien
2002.07.30, 09:56 PM
I am problems with making things random. The problems should be easy to fix, but I've been reading and I still can't figure out whats wrong.

A) I want srand(); to make a true random start from some kind of time function. The command TickCount() and clock() (basically the same things) only gives the counts since the program started (so they are the same each time). There are some calender functions but those are updated to slowly. How can I find the time since the computer has started up or something?


B) When I say a=rand(); would expect a to be a new random number and to hold that number. However, a keeps changing!? Oh what oh what do I do?

OneSadCookie
2002.07.30, 10:10 PM
1) The standard thing to do to randomize rand() is srand(time(NULL)). You'll need to include <time.h> as well as <stdlib.h>. time() returns the number of seconds since midnight January 1st 1970 UTC.

2) Each time you say a = rand(), you give a a new value. If you only say it once, you'll only get one value.

3) rand() is not a very good random number generator. In particular, on BSD unices (including MacOSX), the last few digits tend to cycle predictably. If you're only writing for a BSD, you can use random() and srandom() instead. Otherwise, if you really care about randomness, use the high digits of the random number rather than the low ones.

Mars_999
2002.07.30, 10:20 PM
You need to seed your rand() first. You can do a search around idevgames I know this subject has been asked before. Not sure due to it has been awhile but think this is how you seed rand()?


int x = 0;
unsigned int seed = 10;
srand(seed);
x = rand();


Now if you want to seed your random numbers to time, not sure if this is correct but,


int x = 0;
unsigned int time = 0;
//use () to get system time here
//time = GetSystemTime();
srand(time);
x = rand();


I am probably wrong on this but its been awhile since I have used the rand() to generate numbers! =) HTH

ibullard
2002.07.30, 11:33 PM
The easy answer is never, ever use rand(). Ever. Never, ever. It's slow and usually not that random. If you're more into randomness than speed, the Mersenne Twister (http://www.math.keio.ac.jp/%7Ematumoto/emt.html) is very "random." If you're looking for speed, de Groot (http://www.immersive.com/marc/dgrand.html) seems to be reasonably random and fast. Flipcode recently had a post of a very fast random number generator, but I don't know how "random" it is (my own implementation of it):

class flipRand
{
public:
unsigned int rand()
{
m_high = (m_high<<16) + (m_high>>16);
m_high += m_low;
m_low += m_high;
return m_high;
}
void init(unsigned int seed) { m_low = seed; m_high = ~seed; }

int m_high;
int m_low;
};


As for seed generation, I think other people covered that very well.

OneSadCookie,

What header do you need to include for random() and srandom()? I'm having a hard time finding it (probably because it's right in front of my face).

Douglas O'Brien
2002.07.31, 12:10 AM
Thanks for the time() thing. And I found out why I kept getting a different answer for a. I thought I had the a=rand(); somewehre where it wasn't.

Thnx all.

OneSadCookie
2002.07.31, 02:21 AM
What header do you need to include for random() and srandom()? I'm having a hard time finding it (probably because it's right in front of my face).

I'm guessing so :D -- they're in <stdlib.h>, home of rand() and srand().

Note that they're neither ANSI nor POSIX.

OneSadCookie
2002.07.31, 02:23 AM
Incidentally, the speed of the Mersenne Twister is comparable with the speed of rand() on both MacOSX and Linux, but it's much more random than rand() on the Mac.

Pazolli
2002.07.31, 06:30 AM
OneSadCookie's right you should never ever use rand(). However rather than write your own rand() function why not use random() you can find out more about it by typing "man 3 random" (I think) in the Mac OS X Terminal. It's much more random than rand() (so to speak).

Cheers.

ibullard
2002.07.31, 11:06 AM
Actually, I've been writing an article about this topic for a while now (I'm working 70hours/week at my job so it's taking me a long time to finish it). In short, I'm comparing std::rand(), de Groot, the flipcode version above, and the Merseanne Twister using the ENT and Diehard tests as well as timing each of them.

Here's the result of the speed tests:
(Firewire Powerbook - G3 400, 640MB RAM, OS X.1.5, Codewarrior 7)
numbers are the number of milliseconds it took to generate 500,000 random numbers
std::rand() - 320
de Groot - 452
flipCode - 185
Merseanne Twister - 923

random() doesn't seem to be available in CW 7 and the std::rand() only provides numbers between 0 and 32767. I'll probably port my project over to Apple's dev tools and add random() to the test before finishing the article.

OneSadCookie
2002.07.31, 03:31 PM
That's rand() on MacOS9. rand() on MacOSX is about the same speed as the Mersenne Twister, produces numbers between 0 and 0x7fffffff ((1 << 31) - 1), and isn't very random in the least significant digits.

AFAIK, Metrowerks' rand() implementation simply calls through to the QuickDraw random function.

ibullard
2002.07.31, 06:05 PM
Good to know. Thanks, OneSadCookie. I'll add random() and OSX rand() to the list of generators I'm comparing.