 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kurdayon@yahoo.com Guest
|
Posted: Wed Jan 19, 2005 11:18 pm Post subject: Randomizer by time. |
|
|
Hello,
to generate random integer number from a given range I use the
following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is small I
get the same numbers. The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this problem. Can you help me?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maciej Sobczak Guest
|
Posted: Thu Jan 20, 2005 11:51 am Post subject: Re: Randomizer by time. |
|
|
Hi,
[email]kurdayon (AT) yahoo (DOT) com[/email] wrote:
| Quote: | Hello,
to generate random integer number from a given range I use the
following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is small I
get the same numbers. The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this problem. Can you help me?
|
Just do not clump these two lines together.
Normally, I would expect srand() to be called *once* (for example, at
the beginning of the program or anytime before the first rand() is
called). After doing that, call only rand(), as many times as you want.
Another issue is that your formula for "random" number from a given
range may not give a uniform distribution, depending on the relation
between Nmax and RAND_MAX.
See also: http://www.eskimo.com/~scs/C-faq/q13.16.html
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jack Klein Guest
|
Posted: Thu Jan 20, 2005 11:52 am Post subject: Re: Randomizer by time. |
|
|
On 19 Jan 2005 18:18:47 -0500, [email]kurdayon (AT) yahoo (DOT) com[/email] wrote in
comp.lang.c++.moderated:
| Quote: | Hello,
to generate random integer number from a given range I use the
following lines:
srand(time(0));
|
Note that this code does not necessarily have defined behavior,
depending on the type used for size_t by the implementation and the
value that size_t might contain.
| Quote: | tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is small I
get the same numbers. The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this problem. Can you help me?
|
It is a very common newbie mistake to call srand() before every call
to rand(). There is almost never an actual reason to call srand()
more than once. In general, call srand() once only at the start of
the program, then call rand() as often as you like.
See also the questions about random numbers in section 13 of the FAQ
for comp.lang.c, here http://www.eskimo.com/~scs/C-faq/s13.html. They
apply equally well in C++.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ian McCulloch Guest
|
Posted: Thu Jan 20, 2005 12:18 pm Post subject: Re: Randomizer by time. |
|
|
[email]kurdayon (AT) yahoo (DOT) com[/email] wrote:
| Quote: | Hello,
to generate random integer number from a given range I use the
following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is small I
get the same numbers. The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this problem. Can you help me?
|
You should initialize the random seed just once at the start of the program
and then leave it. rand() will return a more-or-less random sequence
without further intervention. Setting the seed more frequently is
pointless, and in this case - where the seed has practically zero entropy -
will destroy whatever randomness properies your implementation of rand()
has anyway.
HTH,
Ian
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Thu Jan 20, 2005 12:19 pm Post subject: Re: Randomizer by time. |
|
|
| Quote: | to generate random integer number from a given
range I use the following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of
these lines is small I get the same numbers.
The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this
problem. Can you help me?
|
Call 'srand()' only once, then obtain consecutive numbers by calling just
'rand()'.
BR
Grzegorz
--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Efrat Regev Guest
|
Posted: Thu Jan 20, 2005 12:23 pm Post subject: Re: Randomizer by time. |
|
|
Hello,
The boost libraries contain very good random-number classes by Jens
Maurer. One of the things you can see is that you can create a
randomization engine object, and use it for random number generators. The
possible relevance for you is that, in this design, you only need to "srand"
only a "global" engine object. Consequently, ::time(0) will be called only
once per program execution, and, therefore, subsequent calls to ::time(0)
will be far apart in time.
I hope this helps
<kurdayon (AT) yahoo (DOT) com> wrote
| Quote: | Hello,
to generate random integer number from a given range I use the
following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is small I
get the same numbers. The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this problem. Can you help me?
|
[ 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
|
Posted: Thu Jan 20, 2005 6:17 pm Post subject: Re: Randomizer by time. |
|
|
[email]kurdayon (AT) yahoo (DOT) com[/email] wrote:
| Quote: | to generate random integer number from a given range I use the
following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is
small I get the same numbers. The cause is clear (argument
time in strand is the same). Not clear is how I can resolve
this problem. Can you help me?
|
You're only supposed to call srand() once, at the beginning of
the program.
--
James Kanze GABI Software http://www.gabi-soft.fr
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 |
|
 |
Peter Koch Larsen Guest
|
Posted: Thu Jan 20, 2005 6:22 pm Post subject: Re: Randomizer by time. |
|
|
<kurdayon (AT) yahoo (DOT) com> skrev i en meddelelse
news:1106164595.205998.84760 (AT) c13g2000cwb (DOT) googlegroups.com...
| Quote: | Hello,
to generate random integer number from a given range I use the
following lines:
srand(time(0));
tmp = Nmin + rand() % Nmax;
However, if interval between subsequent call of these lines is small I
get the same numbers. The cause is clear (argument time in strand is
the same). Not clear is how I can resolve this problem. Can you help me?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
You should call srand only once in your program. |
/Peter
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Joseph Turian Guest
|
Posted: Fri Jan 21, 2005 10:27 am Post subject: Re: Randomizer by time. |
|
|
Why are you using rand() instead of the rand48 functions?
You'll get much better random numbers that way.
Joseph
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Sat Jan 22, 2005 4:54 am Post subject: Re: Randomizer by time. |
|
|
Joseph Turian wrote:
| Quote: | Why are you using rand() instead of the rand48 functions?
You'll get much better random numbers that way.
|
Probably because they are not standard and their availability depends on
the environment..?
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sat Jan 22, 2005 5:00 am Post subject: Re: Randomizer by time. |
|
|
In article <1106263173.522428.185130 (AT) z14g2000cwz (DOT) googlegroups.com>,
Joseph Turian <turian (AT) gmail (DOT) com> writes
| Quote: | Why are you using rand() instead of the rand48 functions?
You'll get much better random numbers that way.
|
But not much use if you are trying to write portable C++, and not much
use if you are using an implementation where long is only 32 bits.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ 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
|
Posted: Sat Jan 22, 2005 5:33 am Post subject: Re: Randomizer by time. |
|
|
Jack Klein wrote:
| Quote: | On 19 Jan 2005 18:18:47 -0500, [email]kurdayon (AT) yahoo (DOT) com[/email] wrote in
comp.lang.c++.moderated:
to generate random integer number from a given range I use
the following lines:
srand(time(0));
Note that this code does not necessarily have defined
behavior, depending on the type used for size_t by the
implementation and the value that size_t might contain.
|
Technically, no, although it may not do anything useful. (I am
supposing that your size_t is a typo for time_t. If not, I
don't understand; there's not a single size_t in sight.)
If the necessary headers have not been included, then of course,
it has undefined behavior. Always. If they have been included,
then there should be no problem -- the time_t returned by time()
is an arithmetic type, which can be implicitely converted to the
unsigned int which srand expects. If the value cannot be
represented as an unsigned int, then the results of the
conversion are implementation defined (and may result in an
implementation defined signal, at least in C99); implementation
defined, and not undefined.
Of course, on a 16 bit machine, with a Unix-like time_t, you
probably will get an implementation defined signal, if that is
what the implementation does. And if the implementation
represents time in megayears since 1900, on a double, you're not
likely to get a useful seed, even without the signal:-).
But it is a consacrated idiom:-).
--
James Kanze GABI Software http://www.gabi-soft.fr
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
|
Posted: Sat Jan 22, 2005 5:36 am Post subject: Re: Randomizer by time. |
|
|
Joseph Turian wrote:
| Quote: | Why are you using rand() instead of the rand48 functions?
You'll get much better random numbers that way.
|
First, of course, because rand48 is not portable. It's not part
of Unix and it isn't present on Windows. There is a drand48 in
the Open System extensions, but it's not Posix, and it isn't
present on Windows either.
Generally speaking, I think that the ?rand48 functions were
introduced in Berkley Unix, because the rand() in the original
Unix library was so bad. The actual function specified in the
Open System's standards doesn't look all that good to me, and a
lot of the rand() today have improved, so I'm not sure that
?rand48 is necessarily that much better. If you want to be sure
of the quality of your random number generator, the only
solution is to adopt a single implementation of known quality.
Boost::random offers a lot, for example -- if you can't find
what you need there, I don't know where you'll find it.
Note too that just taking the modulo of the results will
introduce some skewing toward the lower values.
--
James Kanze GABI Software http://www.gabi-soft.fr
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 |
|
 |
Joseph Turian Guest
|
Posted: Sun Jan 23, 2005 2:40 am Post subject: Re: Randomizer by time. |
|
|
Seungbeom Kim writes:
| Quote: | Probably because they are not standard and their availability depends
on
the environment..?
|
Fair enough.
Francis Glassborow writes:
| Quote: | not much use if you are using an implementation where long is only 32
bits. |
Uh... why not?
| Quote: | From the drand48 manpage on Linux:
The lrand48() and nrand48() functions return non-negative long |
integers
uniformly distributed between 0 and 2^31.
The mrand48() and jrand48() functions return signed long
integers uni-
formly distributed between -2^31 and 2^31.
Alternately:
unsigned long myrand(unsigned long ceiling) {
return (unsigned long)(drand48() * ceiling);
}
James Kanze writes:
| Quote: | Note too that just taking the modulo of the results will
introduce some skewing toward the lower values.
|
True, depending upon your implementation. And since Seungbeom seems to
be interested in using rand() on platforms where the implementation
might be poor, he should heed your warning.
| Quote: | From the rand() manpage:
In Numerical Recipes in C: The Art of Scientific Computing |
(William H.
Press, Brian P. Flannery, Saul A. Teukolsky, William T.
Vetterling; New
York: Cambridge University Press, 1992 (2nd ed., p. 277)), the
follow-
ing comments are made:
"If you want to generate a random integer between 1 and
10, you
should always do it by using high-order bits, as in
j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
and never by anything resembling
j=1+(rand() % 10);
(which uses lower-order bits)."
Joseph
[ 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
|
Posted: Mon Jan 24, 2005 9:02 pm Post subject: Re: Randomizer by time. |
|
|
Joseph Turian wrote:
| Quote: | Seungbeom Kim writes:
Probably because they are not standard and their
availability depends on the environment..?
Fair enough.
Francis Glassborow writes:
not much use if you are using an implementation where long
is only 32 bits.
Uh... why not?
From the drand48 manpage on Linux:
The lrand48() and nrand48() functions return non-negative long
integers uniformly distributed between 0 and 2^31.
The mrand48() and jrand48() functions return signed long
integers uni- formly distributed between -2^31 and 2^31.
Alternately:
unsigned long myrand(unsigned long ceiling) {
return (unsigned long)(drand48() * ceiling);
}
James Kanze writes:
Note too that just taking the modulo of the results will
introduce some skewing toward the lower values.
True, depending upon your implementation.
|
Depending on the value you are using for the modulo and the
implementation. If the value is a divisor of RAND_MAX+1, there
will be no skew. But since RAND_MAX+1 will be a prime number if
you are using a good linear congruent generator (which are still
by far the most common), there is a good chance that it isn't a
divisor. And of course, if you use % 6 one time, and %8 the
next, at least one of the two will manifest skew.
| Quote: | And since Seungbeom seems to be interested in using rand() on
platforms where the implementation might be poor, he should
heed your warning.
From the rand() manpage:
In Numerical Recipes in C: The Art of Scientific Computing
(William H.
Press, Brian P. Flannery, Saul A. Teukolsky, William T.
Vetterling; New
York: Cambridge University Press, 1992 (2nd ed., p. 277)), the
follow-
ing comments are made:
"If you want to generate a random integer between 1 and 10,
you should always do it by using high-order bits, as in
j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
and never by anything resembling
j=1+(rand() % 10);
(which uses lower-order bits)."
|
IMHO, that's not really good advice. If you have a bad
generator, using the high order bits won't make it a good one;
it just means that you won't see the weakness as easily. If you
have a good generator, using the low order bits is fine.
None of which, of course, changes the fact that the modulo
introduces skew toward the lower values. Regardless of the
generator used.
--
James Kanze GABI Software http://www.gabi-soft.fr
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 |
|
 |
|
|
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
|
|