C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Rand() is Nice but Slow
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
charlesrkiss
Guest





PostPosted: Sun Jun 05, 2005 10:25 am    Post subject: Rand() is Nice but Slow Reply with quote



The rand() literature and links I've been given here are excellent,
thank you so much people!

A coin toss game using outcomes on rand() would require one second for
the srand() seed to initialize rand(). What is the simplest method to
which a random number can be generated quickly in C++?

Tangent 1:The energy requirements would be, at minimum, a
photon-electron detection, amplified; that would be a hardware device
imbedded: What different clocks on the processor motherboard and
peripherals are used and available for C++ random number generators?.

Tangent 2:This energy minimum would be restrained by the accuracy of
the measuring device relative to the ratio of the expected value to the
measured time between detections (photon-electron collisions). The
higher the frequency, the higher the energy, and the more accurate the
measuring device, the faster could the program be.

It would be nice to generate random numbers more quickly if there was a
faster and more accurate clock. Hey maybe a faster more inaccurate
clock!

Ah, they're all the same.
Charles


ps. Again, thanks for the info and links; I'll look more into it. It's
a fascinating sort of information processing, I like the
software-pseudorandom-generator and hardware-random-generator, thing.
Thanks!


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
James Kanze
Guest





PostPosted: Sun Jun 05, 2005 6:54 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote



charlesrkiss wrote:
Quote:
The rand() literature and links I've been given here are
excellent, thank you so much people!

A coin toss game using outcomes on rand() would require one
second for the srand() seed to initialize rand().

Why? You initialize the random sequence once, with whatever
pseudo-random value you want. (I usually use a hashcode of the
process id, the hostname and the results of time().) The time
it takes to seed the generator will depend on the algorithm
used, but it will usually be fairly small (say, less than a
millisecond), and you only do it once.

What does count, of course, is the time it takes to generate
each successive random value after that (the call to rand()).
This depends largely on the algorithm used; in practice, the
best algorithms aren't necessarily the fastest, but just because
an algorithm is slow doesn't mean that it is good. Generally
speaking, it should be possible to generate reasonably good
random numbers with something around 10 machine instructions --
a couple of microseconds on my machine.

Quote:
What is the simplest method to which a random number can be
generated quickly in C++?

How quickly, and how random? Linear congruent generators can be
quite rapid, and if the constants are correctly chosen, fairly
good as well.

Other than that, some systems have a peripheral device
(/dev/random on a Unix system, if it exists) which generates
random byte. How random, and how fast, depends on the system
and the hardware, of course. (A quick test on my Linux machine
shows that the speed is significantly below that of my software
pseudo-generators -- by several orders of magnitude. On the
other hand, there's be no problem in using it to generate the
seed of a software generator. Or even to generate a new seed
every couple of seconds, if that's what you want.

--
James Kanze mailto: [email]james.kanze (AT) free (DOT) fr[/email]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carlos Moreno
Guest





PostPosted: Mon Jun 06, 2005 7:15 am    Post subject: Re: Rand() is Nice but Slow Reply with quote



charlesrkiss wrote:
Quote:
The rand() literature and links I've been given here are excellent,
thank you so much people!

A coin toss game using outcomes on rand() would require one second for
the srand() seed to initialize rand().

I think you misunderstood. srand() has to be called only once, at
the beginning of execution (or more specifically, prior to the first
call to rand()). And it does not take one second to execute.

The expression srand(time(NULL)) causes the program to read the
current date/time (more specifically, the number of seconds since
Jan 1, 1970) and uses that value to initialize the sequence of
pseudo-random numbers.

After you call rand(), subsequent values are different.

Did you read about Linear Congruential generators? That's what
rand() does. It's something similar to the following:

unsigned int x;

void srand (int seed)
{
x = seed;
}

int rand()
{
x = (x * A + B) % M;
return int(x);
}

Where the values of A, B, and M, are chosen to optimize the
statistical properties of the sequence (well, M is typically a
power of 2 for efficiency reasons).

As you can see, the sequence is fixed -- all you're doing with
srand is specifying at which point of the whole sequence you
want to start for the current execution.

Quote:
What is the simplest method to
which a random number can be generated quickly in C++?

srand(time(NULL)), and then call rand() to obtain pseudo-random
numbers.

Now, again, these are *NOT* random numbers -- depending on the
application, not even close!

If your system is to run on a Unix/Linux system, then reading
bytes from /dev/urandom or /dev/random is a safe bet -- those
are as close to truly random numbers as you'll want for virtually
any application; they are generated from data gathered from
events external to the computer (typically timing of hardware
interrupts and other events that are really random in nature).

If the "coin toss game" you're talking about is an informal
game for your own fun, then rand() would do the job more than
well enough.

If you're talking about something more serious like, say, an
online game where there's money (or other benefits) involved
for the winner, then you have to avoid, at all costs, anything
that is fully predictable.

In the book "Building Secure Software", in the chapter on random
numbers, they tell an anecdote of this online poker game where
some hackers, knowing that the random numbers were generated
with rand(), seeded with the time (in milliseconds), wrote a
program that could determine all the players' cards (and the
upcoming carsd) by just entering 5 cards already seen. The
program simply used the approximate date/time, and then try
some 50 thousand possible values (to account for discrepancies
between the server's and your clock) until one possibility
matches the 5 cards. This is the result of shuffling things
with a procedure that, even though produces something randomish
and patternless to the eye, is fully predictable and trivial
to reproduce.

HTH,

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Uenal Mutlu
Guest





PostPosted: Mon Jun 06, 2005 7:16 am    Post subject: Re: Rand() is Nice but Slow Reply with quote

"charlesrkiss" <charles (AT) kissbrothers (DOT) com> wrote
Quote:
The rand() literature and links I've been given here are excellent,
thank you so much people!

A coin toss game using outcomes on rand() would require one second for
the srand() seed to initialize rand(). What is the simplest method to
which a random number can be generated quickly in C++?

You should do srand() only once in your whole app.
You shouldn't use an app to create just a rand number, otherwise
you are calculating the app load+execution times.
Your app should in main call srand(time(0)) once, and then
enter a processing loop wherin rand() calls would be made.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carlos Moreno
Guest





PostPosted: Mon Jun 06, 2005 7:24 am    Post subject: Re: Rand() is Nice but Slow Reply with quote

James Kanze wrote:

Quote:
Other than that, some systems have a peripheral device
(/dev/random on a Unix system, if it exists) which generates
random byte. How random, and how fast, depends on the system
and the hardware, of course. (A quick test on my Linux machine
shows that the speed is significantly below that of my software
pseudo-generators -- by several orders of magnitude.

I know that coming from you, I shouldn't expect this oversight,
but just in case, I'll ask: are you sure that you're not running
out of entropy?

(i.e., using /dev/random instead of /dev/urandom)

I remember reading recently that /dev/urandom simply does a SHA1
hash of the entropy pool -- is computing a SHA1 several orders of
magnitude slower than a LCG operation? (perhaps a few hundred
times slower, I'm guessing)

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Keith H Duggar
Guest





PostPosted: Mon Jun 06, 2005 7:27 am    Post subject: Re: Rand() is Nice but Slow Reply with quote

If you are going to use a linear congruential generator,
especially on a 32 bit machine then the following constants
from the BCPL language will work well

/* given a random 32 bit interger x the next x is given by*/

x = x * 2147001325 + 715136305

/* suggested references are Knuth and
http://random.mat.sbg.ac.at/~c harly/server/node3.html */

This generator has several advantages other LCG's for 32 bit
machines.

1) the period is the full 2^32

2) zero is a valid number

3) on a two's complement machine both unsigned AND signed
integers work just fine giving you a very nice way of
generating negative or positive values

4) the spectral coefficients are better than the Park and
Miller minimal standard in dimensions 2,3,4,5,7, and 8
and the lattice structure in 2 dimensions is more uniform

5) compared to typical LCG's using Schrage's method it is
MUCH faster

1 mul , 1 add versus
2 mul , 1 add , 1 div , 1 mod


Point (5) is because a large modulus that is not a power of
two must use Schrage's and even if the multiplier is small
enough you must still do at least one modulo which is many
times slower than an add or a multiply. One the other hand
using this power of two modulus 2^32 you get the modulo for
free on a 32 bit machine.

The equation I gave you is so simple that you don't even
need a class. Just cut and past the code wherever you want
to use it and pay absolutely no overhead.

If you need random numbers better than an LCG download and
use a Mersenne Twister implementation or if you don't mind
low order bit coalescene then you might try and a lagged
fibonacci generator.

But, for game code or just playing around the BCPL generator
rules.

PS. If anyone out there has any other excellent 32 bit
modulus multiplier- offset pairs PLEASE post them. Please
stick to LCG with an offset so we get the full period. I'm
particularly curious if anybody knows of any
multiplier-offset pairs that individually fit into 16 bits.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
charlesrkiss
Guest





PostPosted: Mon Jun 06, 2005 7:27 am    Post subject: Re: Rand() is Nice but Slow Reply with quote

Hi James,

Thanks for your reply.

My needs are to generate random numbers within a single source file;
"random_number" modulus two, and run them through an if statement. To
get a random distribution of zeros and ones into an array. Other
games will include zeros, ones and threes; and so on.

I would like the speed of the random number generation to be not
limited by the time() function in srand(time()) "seeder" as it is in
the program I am writing now -because the new seed is generating only
after each new second on the time clock. But I'm rather new to this
stuff. **I ran the program twice in less than a second and got the
same number**

The /dev/random on my Debian workstation is there, but I can't get to
it as root (permission denied); do I mount it onto something? Then
what? I'll look into it. That sounds totally cool! Thanks! How
does it work?? Is it a hardware random number generator?? What's the
data type?

Thanks again,
Charles


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ralf Fassel
Guest





PostPosted: Mon Jun 06, 2005 11:19 am    Post subject: Re: Rand() is Nice but Slow Reply with quote

* "charlesrkiss" <charles (AT) kissbrothers (DOT) com>
Quote:
**I ran the program twice in less than a second and got the same
number**

That's why James suggested
(I usually use a hashcode of the process id, the hostname and the
results of time().)
as a seed, not only the result of time() (which obviously will not
change within a second).

Quote:
The /dev/random on my Debian workstation is there, but I can't get to
it as root (permission denied); do I mount it onto something?

Hmmm,
% ls -l /dev/*random
crw-rw-rw- 1 root root 1, 8 Apr 6 2004 /dev/random
crw-r--r-- 1 root root 1, 9 May 24 19:16 /dev/urandom

should be able to std::ifstream.open() it and read the initial byte(s)
for seed()?

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

const char *rand_device = "/dev/urandom";
// const char *rand_device = "/dev/random";

int
main() {
cout << "uid " << getuid() << endl;
std::ifstream random(rand_device);
if (!random) {
perror(rand_device);
return 1;
}

unsigned int seed;
random.read((char*)&seed, sizeof(seed));
cout << "seed: " << seed << endl;
return 0;
}

# g++ -o t t.cxx
# ./t ; ./t ; ./t ; ./t
uid 0
seed: 3131529725
uid 0
seed: 2170299913
uid 0
seed: 2517196338
uid 0
seed: 2856246273

Note that /dev/random may block in the read() call if there is not
enough 'entropy' (see docs for details).

R'

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jun 06, 2005 2:35 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote

Carlos Moreno wrote:
Quote:
James Kanze wrote:

Other than that, some systems have a peripheral device
(/dev/random on a Unix system, if it exists) which generates
random byte. How random, and how fast, depends on the
system and the hardware, of course. (A quick test on my
Linux machine shows that the speed is significantly below
that of my software pseudo-generators -- by several orders
of magnitude.

I know that coming from you, I shouldn't expect this
oversight, but just in case, I'll ask: are you sure that
you're not running out of entropy?

No idea. To tell the truth, I just happened to notice the
device by accident. I've never seen any documentation about it.
When I needed a good random generator seed, I used the code I
posted in my other posting. (FWIW: I used a random number
generator for the first time professionally last week. For some
reason, banks and telephone companies tend to frown on random
behavior in booking stock market orders or routing phone
calls:-).)

I might add that there was absolutely nothing rigorous or
scientific about my measurements. I simply read /dev/random
using my xd program (which displays a file in hex), and remarked
that there were noticeable hesitations in the output to the
xterm window. Given that I was running on a relatively powerful
machine (and AMD 3000 64 bits) with a reasonable amount of
memory (512 MB), and that the machine wasn't really doing
anything else, I charged the hesitations to /dev/random.

On the other hand, the program started, and output the first
couple of lines, rapidly, so I don't think it would be a problem
using the device to generate a seed.

Quote:
(i.e., using /dev/random instead of /dev/urandom)

So what's the difference. I've got both on my Sparc, here, but
I can't find any documentation for either.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jun 06, 2005 2:36 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote

Keith H Duggar wrote:
Quote:
If you are going to use a linear congruential generator,
especially on a 32 bit machine then the following constants
from the BCPL language will work well

/* given a random 32 bit interger x the next x is given by*/

x = x * 2147001325 + 715136305

/* suggested references are Knuth and
http://random.mat.sbg.ac.at/~charly/server/node3.html */

This generator has several advantages other LCG's for 32 bit
machines.

It also has a very significant disadvantage -- it is a very poor
generator, alternating even and odd. For a very simple test:
simulating 100000 throws of a pair of dice, 2, 4, 6, 8, 10 and
12 never showed up. I would say that this renders it unsuitable
even for simple games, much less for any serious work.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jun 06, 2005 2:37 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote

Carlos Moreno wrote:
Quote:
charlesrkiss wrote:

Did you read about Linear Congruential generators? That's
what rand() does.

That's not a requirement.

There's also no guarantee concerning the quality -- "return 0"
would, I think, be a conforming implementation of rand(). The C
standard does present an "example" of a portable implementation
of rand() and srand(). Regretfully, their "portable"
implementation is only marginally better than "return 0"; if you
check it, I think you'll find that it alternates odd and even
values, which isn't very "random" by any defintion I know.

Quote:
It's something similar to the following:

unsigned int x;

void srand (int seed)
{
x = seed;
}

int rand()
{
x = (x * A + B) % M;
return int(x);
}

Where the values of A, B, and M, are chosen to optimize the
statistical properties of the sequence (well, M is typically a
power of 2 for efficiency reasons).

Choosing the correct values is almost a black science. A
certain number of things are known, however: that B == 0 works
as well as any other value (and typically saves one machine
instruction), and that M must be a prime number. (I think the
low order bit has a period of the smallest factor of M, or
something like that. At any rate, if M is a power of 2, the low
order bit simply alternates.)

The traditional response to this is to simply not use the low
order bits -- if you wanted a random number between 1 and 6, for
example, you would use something like (rand()>>7) % 6. This
might be OK for a simple game, but for anything serious, I would
use a reliable generator, even if it meant writing it myself.

The reference for linear congruent generators is "Random Number
Generators: Good Ones Are Hard to Find", Park and Miller, CACM,
Oct. 1988, Vol. 31, No. 10, pp. 1192-1201. Some "good" values
for linear congruent generators are A=48271, M=2147483647 and
A=40692, M=2147483399 (both from the Errata to "The Art of
Computer Programming, Volume 2" (by Donald Knuth, but if you're
not familiar with this book, you should go back and start over).

I've heard that a new algorithm, the Mersenne twister, gives
even better random numbers, but I'm not really familliar with
it.

Boost has templated wrappers for these and other algorithms.

Quote:
As you can see, the sequence is fixed -- all you're doing with
srand is specifying at which point of the whole sequence you
want to start for the current execution.

What is the simplest method to which a random number can be
generated quickly in C++?

srand(time(NULL)), and then call rand() to obtain
pseudo-random numbers.

Now, again, these are *NOT* random numbers -- depending on the
application, not even close!

If your system is to run on a Unix/Linux system, then reading
bytes from /dev/urandom or /dev/random is a safe bet -- those
are as close to truly random numbers as you'll want for
virtually any application; they are generated from data
gathered from events external to the computer (typically
timing of hardware interrupts and other events that are really
random in nature).

How standard are they? They're present on my Solaris based
system at work, and my Linux system at home, but I couldn't find
any mention of them in Posix or the Open System specification.

Quote:
If the "coin toss game" you're talking about is an informal
game for your own fun, then rand() would do the job more than
well enough.

Not if it implements the version of rand() suggested in the C
standard.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jun 06, 2005 2:48 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote

charlesrkiss wrote:

Quote:
My needs are to generate random numbers within a single source
file; "random_number" modulus two, and run them through an if
statement. To get a random distribution of zeros and ones
into an array. Other games will include zeros, ones and
threes; and so on.

I would like the speed of the random number generation to be
not limited by the time() function in srand(time()) "seeder"
as it is in the program I am writing now -because the new seed
is generating only after each new second on the time clock.
But I'm rather new to this stuff. **I ran the program twice
in less than a second and got the same number**

I'm not quite sure what problem you're trying to describe.
Normally, when one speaks of "speed" of a program, what is meant
is CPU time. All of the implementations of rand() take a lot
less than a second. A couple of microseconds per call would be
typical.

On the other hand, part of your statement seems to speak more
about a problem of starting the program several times in the
same second, and getting the same values. If you just use
time() to initialize the generator, this is the effect you will
get. As I said, I use a FNV hash code of the machine name, the
process id and the time(); any two programs starting within the
same second on the same machine are almost certain to have
different process ids. I'm currently using:

unsigned int result = 2166136261U ;
char buffer[ 1000 ] ;
gethostname( buffer, sizeof( buffer ) ) ;
for ( char const* p = buffer ; *p != '' ; ++ p ) {
result = 16777619U * result + (unsigned char)*p ;
}
result = 16777619U * result + time( NULL ) ;
result = 16777619U * result + getpid() ;

Quote:
The /dev/random on my Debian workstation is there, but I can't
get to it as root (permission denied); do I mount it onto
something?

It sounds like a configuration problem. Both on my Linux box at
home (Mandrake) and my Sparc here at work (Solaris), I have no
problem reading /dev/random as an ordinary user. Under Solaris,
the rights are crw-r--r--, which sounds about right.

Quote:
Then what?

Just read it. (Don't forget to open in binary mode.) It
generates a never ending stream of random bytes. My impression
is that it is too slow to be used as a primary source for random
numbers (e.g. in a game), but it should be a good source for
generating a seed -- just read the first four bytes, and pack
them into an unsigned int. Although not very elegant, just
reading sizeof( unsigned int ) bytes directly into the variable
(using a reinterpret_cast to pass its address to istream::read)
should be largely sufficient for this use.

Quote:
I'll look into it. That sounds totally cool! Thanks! How
does it work?? Is it a hardware random number generator??
What's the data type?

I've no idea how it works, but I suppse that it is hardware
based somehow. Like everything else under Unix, it's a byte
stream; it's up to you to turn it into anything else.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Branimir Maksimovic
Guest





PostPosted: Mon Jun 06, 2005 7:47 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
Carlos Moreno wrote:
On the other hand, the program started, and output the first
couple of lines, rapidly, so I don't think it would be a problem
using the device to generate a seed.

(i.e., using /dev/random instead of /dev/urandom)

So what's the difference. I've got both on my Sparc, here, but
I can't find any documentation for either.


/dev/urandom is pseudo random, it's consideraby faster then
/dev/random which is true random.
On linux in mt environment I use /dev/urandom instead of rand,
because rand uses mutex and makes lock contention, if more then one
thread calls it.

Greetings, Bane.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Keith H Duggar
Guest





PostPosted: Mon Jun 06, 2005 7:48 pm    Post subject: Re: Rand() is Nice but Slow Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:

Quote:
Regretfully, their "portable" implementation is only
marginally better than "return 0"; if you check it, I
think you'll find that it alternates odd and even values,
which isn't very "random" by any defintion I know.

It also has a very significant disadvantage -- it is a
very poor generator, alternating even and odd.

Hold on, it is well known that any full period LCG with a
even modulus alternates even and odd (ANSIC, BCPL, and many
others). This does not make them 'poor' generators nor does
it give them a 'very significant disadvantage' to other
LCG's. You just need to know that they alternate and deal
with it appropriately IF needed. For example in your test

Quote:
For a very simple test: simulating 100000 throws of a pair
of dice, 2, 4, 6, 8, 10 and 12 never showed up. I would
say that this renders it unsuitable even for simple games,
much less for any serious work.

You did not show your code but from your result I can safely
assume that you used modulus to map from the full range to a
range with cardinality 6 ([0 ... 5] for example). Using
modulus to achieve this mapping is a 'very poor' method no
matter which LCG you use. The 'correct' way is to divide by
the modulus to map to [0.0 ... 1.0) and they multiply by the
cardinality. Is this case:

/* if unsigned x is a random number [ 0 ... 2^32-1 ] */
double u = double(x) / (double(unsigned int(-1))+1) ;
int roll = static_cast<int>(u * 6.0) ;

There are slightly less transparent ways to achieve the same
without using floating point math. Thus, in my view it is
your use of the generator not the generator that is flawed.
But we can't know for sure until you present the code.

Even if you wanted to use modulus (which again is flawed)
you can simply shift away the lowest bit (x>>1) and use the
generator as a period 2^31 generator.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Llewelly
Guest





PostPosted: Tue Jun 07, 2005 9:42 am    Post subject: Re: Rand() is Nice but Slow Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] writes:

Quote:
Carlos Moreno wrote:
James Kanze wrote:

Other than that, some systems have a peripheral device
(/dev/random on a Unix system, if it exists) which generates
random byte. How random, and how fast, depends on the
system and the hardware, of course. (A quick test on my
Linux machine shows that the speed is significantly below
that of my software pseudo-generators -- by several orders
of magnitude.

I know that coming from you, I shouldn't expect this
oversight, but just in case, I'll ask: are you sure that
you're not running out of entropy?

No idea. To tell the truth, I just happened to notice the
device by accident. I've never seen any documentation about it.
When I needed a good random generator seed, I used the code I
posted in my other posting. (FWIW: I used a random number
generator for the first time professionally last week. For some
reason, banks and telephone companies tend to frown on random
behavior in booking stock market orders or routing phone
calls:-).)

I might add that there was absolutely nothing rigorous or
scientific about my measurements. I simply read /dev/random
using my xd program (which displays a file in hex), and remarked
that there were noticeable hesitations in the output to the
xterm window. Given that I was running on a relatively powerful
machine (and AMD 3000 64 bits) with a reasonable amount of
memory (512 MB), and that the machine wasn't really doing
anything else, I charged the hesitations to /dev/random.

On the other hand, the program started, and output the first
couple of lines, rapidly, so I don't think it would be a problem
using the device to generate a seed.

(i.e., using /dev/random instead of /dev/urandom)

So what's the difference. I've got both on my Sparc, here, but
I can't find any documentation for either.

Both generate random numbers by gathering entropy from
i/o. /dev/random is more or less direct, and will block until
sufficient entropy has been gathered. /dev/urandom is non-blocking
and will always generate the requested number of bytes, whether or
not sufficient entropy is availible. (I assume this means
/dev/urandom is deterministic when insufficient entropy is
availible, whereas /dev/random is non-deterministic.)

The man page is in section 4 on linux, and in section 7D on solaris.

If you need /dev/random somewhere where it is not availible,
substitutes such EGD: http://egd.sourceforge.net/ exist.

There is a boost component that wraps it:
http://www.boost.org/libs/random/nondet_random.html

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.