Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2006-03

Random numbers

6 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Antal
Show quoted text 8 lines
It's not just that, but randseed is not a threadvar. This means that all your threads use the same randseed variable, so if two threads call "random" at the same time they will still get the same "random" number. Jonas

And also generating a rand * getpid you can't really get good random numbers.
I just made a withdrawal program on this idea, so I've got several repetitions, and upon executing a program again and agian I've got false random numbers, like: a*n; a*(n+1); a*(n+2). That's not a solution anyway.

Maybe a bit shifting or some aritmetical function can help to obtain a more random "looking" number.

I'm trying my next random number generation to filter it with the sin() function, so I can get a bit more entropy :)
(I can't use atmospheric noise as some suggested)

Reply by email

Vinzent Hoefler
to Antal
Antal wrote
Maybe a bit shifting or some aritmetical function can help to obtain a more random "looking" number.

No. Don't do that:

|Random numbers should not be generated with a method chosen at random. | -- Donald E. Knuth

|The generation of random numbers is too important to be left to chance. | -- Robert R. Coveyou, Oak Ridge National Laboratory, 1969

The Mersenne Twister Free Pascal uses is one of the best PRNGs known today, it just has to be used the right way. But calling it from several threads and "randomly" overwriting its state array is definitely not the right way to use it.

Vinzent.

Reply by email

Graeme Geldenhuys
to Antal: And also generating a rand * getpid you can't really get good random numbers. I just made…

Why not use GUID's (or the other name is UUID's) and convert them to a Integer from Hex. You might need to make the GUID value smaller, or part of the GUID (example the last block).

Regards,
- Graeme -

Antal wrote 25 lines
> > It's not just that, but randseed is not a threadvar. This means that > all your threads use the same randseed variable, so if two threads > call "random" at the same time they will still get the same "random" > number. > > > Jonas And also generating a rand * getpid you can't really get good random numbers. I just made a withdrawal program on this idea, so I've got several repetitions, and upon executing a program again and agian I've got false random numbers, like: a*n; a*(n+1); a*(n+2). That's not a solution anyway. Maybe a bit shifting or some aritmetical function can help to obtain a more random "looking" number. I'm trying my next random number generation to filter it with the sin() function, so I can get a bit more entropy :) (I can't use atmospheric noise as some suggested) _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Michalis Kamburelis
to Antal: And also generating a rand * getpid you can't really get good random numbers. I just made…
Antal wrote 19 lines
> > It's not just that, but randseed is not a threadvar. This means that > all your threads use the same randseed variable, so if two threads > call "random" at the same time they will still get the same "random" > number. > > > Jonas And also generating a rand * getpid you can't really get good random numbers. I just made a withdrawal program on this idea, so I've got several repetitions, and upon executing a program again and agian I've got false random numbers, like: a*n; a*(n+1); a*(n+2). That's not a solution anyway. Maybe a bit shifting or some aritmetical function can help to obtain a more random "looking" number.

Like Vinzent pointed out, such tricks are not a really good solution. It seems that most of the thread "Better random numbers ?" concentrated on my trick with "RandSeed := RandSeed * getpid;". But this *was meant to be* just a dirty hack, dirty idea, dirty workaround, whatever.

If you want a real, good solution, see the first part of my initial response. Quoting myself:

"
The proper solution is to use some system-wide generator, that doesn't have to be initialized every time you initialize your program. On Unix, just read /dev/urandom, this should return pseudo-random numbers. On Windows I guess that you will have to do something like that on your own (e.g. write a program in FPC that runs as a service and can be queried for random numbers). (Or you can use Cygwin routines to read Cygwin's /dev/urandom --- never done it, but it should be possible). "

In other words, don't waste too much time trying to improve the
"RandSeed := RandSeed * getpid;" trick.

Michalis

Reply by email

Unknown author
to Vinzent Hoefler: No. Don't do that: |Random numbers should not be generated with a method chosen at random.

Quoting Vinzent Hoefler :

The Mersenne Twister Free Pascal uses is one of the best PRNGs known today, it just has to be used the right way. But calling it from several threads and "randomly" overwriting its state array is definitely not the right way to use it.

Well said.

Maybe you could use a solution where you call the MT random number generator K times for each time the program is run. You "throw away" the first K-1 random values, and return the K'th random value as the random value for this run. Now, for each run, you compute K as some function of (say) the process id, the current time-based seed from randomize, etc.

With this strategy, you would still be picking points off of a good random sequence (from MT), although you would take the random value from a rather poorly-chosen random point in the sequence.

If you can afford the time involved in letting K vary over a large range (relative to the number of times you will call the random number generator), then intuitively I think this would give a pretty good random sequence across runs.

Jeff Miller

Reply by email

Michalis Kamburelis
to Antal: And also generating a rand * getpid you can't really get good random numbers. I just made…

(Second send, it seems that mails from my old email address do not reach fpc lists)

Antal wrote 19 lines
> > It's not just that, but randseed is not a threadvar. This means that > all your threads use the same randseed variable, so if two threads > call "random" at the same time they will still get the same "random" > number. > > > Jonas And also generating a rand * getpid you can't really get good random numbers. I just made a withdrawal program on this idea, so I've got several repetitions, and upon executing a program again and agian I've got false random numbers, like: a*n; a*(n+1); a*(n+2). That's not a solution anyway. Maybe a bit shifting or some aritmetical function can help to obtain a more random "looking" number.

Like Vinzent pointed out, such tricks are not a really good solution. It seems that most of the thread "Better random numbers ?" concentrated on my trick with "RandSeed := RandSeed * getpid;". But this *was meant to be* just a dirty hack, dirty idea, dirty workaround, whatever.

If you want a real, good solution, see the first part of my initial response. Quoting myself:

"
The proper solution is to use some system-wide generator, that doesn't have to be initialized every time you initialize your program. On Unix, just read /dev/urandom, this should return pseudo-random numbers. On Windows I guess that you will have to do something like that on your own (e.g. write a program in FPC that runs as a service and can be queried for random numbers). (Or you can use Cygwin routines to read Cygwin's /dev/urandom --- never done it, but it should be possible). "

In other words, don't waste too much time trying to improve the
"RandSeed := RandSeed * getpid;" trick.

Michalis

Reply by email