srand in c or c++ doesn't really Generate Random Numbers ?

Discussion in 'C++' started by Chelong, Jul 3, 2007.

  1. Chelong

    Chelong Guest

    Hi All
    I am using the srand function generate random numbers.Here is the
    problem.

    for example:
    #include<iostream>
    #include <time.h>

    int main()
    {
    int i = 0,j = 0;

    srand((int)time(0));

    for(i=0; i<10; i++)
    {
    j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
    std::cout << j << '\t';
    }
    std::cout << std::endl;
    return 0;
    }
    result£º
    5 8 8 8 10 2 10 8 9 9
    2 9 7 4 10 3 2 10 8 7

    The problem is that the two lines of the result are the same when the
    compiler run over in one seconds.
    How the function works?
    how the computer make the rand numbers?
    Does the function can generate really Random Numbers ?

    Please help me out if you find some solution for the above problem.
    Thanks in advancs !
    Chelong, Jul 3, 2007
    #1
    1. Advertising

  2. On Jul 3, 12:45 pm, Chelong <> wrote:
    > Hi All
    > I am using the srand function generate random numbers.Here is the
    > problem.
    >
    > srand((int)time(0));
    >

    [code chopped]
    > for(i=0; i<10; i++)
    > {
    > j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
    >
    > The problem is that the two lines of the result are the same when the
    > compiler run over in one seconds.


    time() returns time in seconds. If the seed for srand is same, the
    same random number sequence will be returned. When your program runs
    twice in 1 sec, the seed to srand is same and thus you get the same
    sequence.

    > How the function works?
    > how the computer make the rand numbers?
    > Does the function can generate really Random Numbers ?


    they are "pseudo" random numbers.

    -Neelesh
    Neelesh Bodas, Jul 3, 2007
    #2
    1. Advertising

  3. Chelong

    Hari Guest

    Chelong je napisao:
    > Hi All
    > I am using the srand function generate random numbers.Here is the
    > problem.
    >
    > for example:
    > #include<iostream>
    > #include <time.h>
    >
    > int main()
    > {
    > int i = 0,j = 0;
    >
    > srand((int)time(0));
    >
    > for(i=0; i<10; i++)
    > {
    > j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
    > std::cout << j << '\t';
    > }
    > std::cout << std::endl;
    > return 0;
    > }
    > result£º
    > 5 8 8 8 10 2 10 8 9 9
    > 2 9 7 4 10 3 2 10 8 7
    >
    > The problem is that the two lines of the result are the same when the
    > compiler run over in one seconds.
    > How the function works?
    > how the computer make the rand numbers?
    > Does the function can generate really Random Numbers ?
    >
    > Please help me out if you find some solution for the above problem.
    > Thanks in advancs !


    First: computers can not generate random numbers, instead they
    generate
    pseudo random numbers (most people call them random numbers).

    For decription of srand:
    "The pseudo-random number generator is initialized using the argument
    passed as seed.
    For every different seed value used in a call to srand, the pseudo-
    random number generator can be expected to generate a different
    succession of results in the subsequent calls to rand.
    Two different initializations with the same seed, instructs the pseudo-
    random generator to generate the same succession of results for the
    subsequent calls to rand in both cases.
    If seed is set to 1, the generator is reinitialized to its initial
    value and produces the same values as before any call to rand or
    srand.
    In order to generate random-like numbers, srand is usually initialized
    to some distinctive value, like those related with the execution time.
    For example, the value returned by the function time (declared in
    header <ctime>) is different each second, which is distinctive enough
    for most randoming needs."

    In your program everithing looks fine, on my compiler runs ok (I got
    diferent
    numbers).

    Probably, problem is in your time on computer, try to call time() and
    print results to
    see if you get different values. Also, try to call srand with 1, than
    2, ... and see
    if you get diferent numbers.

    Best,
    Zaharije Pasalic
    Hari, Jul 3, 2007
    #3
  4. Chelong <> writes:

    > Please help me out if you find some solution for the above problem.


    Have a look at Boost's Random module. It's still a pseudo-random generator,
    but there's no way around that without resorting to specialized hardware,
    and it's a much better one than most compilers use.

    <http://www.boost.org>

    Also, from reading the above, I gather that Random is one of several Boost
    modules that are included in TR1, so it's reasonably future-proof.

    sherm--
    Sherm Pendley, Jul 3, 2007
    #4
  5. Chelong

    Chelong Guest

    On 7ÔÂ3ÈÕ, ÏÂÎç4ʱ35·Ö, Sherm Pendley <> wrote:
    > Chelong <> writes:
    > > Please help me out if you find some solution for the above problem.

    >
    > Have a look at Boost's Random module. It's still a pseudo-random generator,
    > but there's no way around that without resorting to specialized hardware,
    > and it's a much better one than most compilers use.
    >
    > <http://www.boost.org>
    >
    > Also, from reading the above, I gather that Random is one of several Boost
    > modules that are included in TR1, so it's reasonably future-proof.
    >
    > sherm--


    u all right!
    thx!
    they are "pseudo" random numbers.
    Chelong, Jul 3, 2007
    #5
  6. Chelong

    James Kanze Guest

    On Jul 3, 10:04 am, Hari <> wrote:
    > Chelong je napisao:


    [...]
    > First: computers can not generate random numbers, instead they
    > generate pseudo random numbers (most people call them random
    > numbers).


    That's not quite true. There are numerous sources of entrophy
    on a modern machine, and depending on what the hardware
    provides, the OS can usually generate truely random numbers.
    Not necessarily very rapidly, however. (Measuring the time
    between mouse clicks in nanoseconds, for example, and then
    taking the low order bits, would be a good example.)

    Unix based machines make this available in "/dev/random". Using
    it as your random number generator is going to make your program
    incredibly slow, but they usually calculate a bit ahead, so you
    can read just a couple of bytes, and use that to seed the random
    number generator.

    Note too that you don't always want real random numbers. Makes
    it awfully hard to reproduce errors for debugging:). The usual
    solution is to use pseudo-random numbers (like rand()), note the
    seed which was used, and provide an option to specify the seed,
    which you can use when you encounter a bug.

    [...]
    > In your program everithing looks fine, on my compiler runs ok
    > (I got diferent numbers).


    He said he only got the same numbers when the program was
    invoked twice in the same second. Which is what one would
    expect. In the absence of "/dev/random", I'll usually bung in a
    number of odd values: the time in microseconds, the process id,
    the IP or the MAP address of the machine, etc., depending on
    what's available, and what the program is designed to do. (If
    it's anything interactive, just time(NULL) is probably
    sufficient. Since I'm usually counting on getting different
    values from programs started by cron jobs at the same time on
    different machines, however...)

    --
    James Kanze (GABI Software) email:
    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
    James Kanze, Jul 3, 2007
    #6
  7. Chelong wrote:
    > srand((int)time(0));


    A quick solution is to use clock() instead of time().
    Juha Nieminen, Jul 3, 2007
    #7
  8. Chelong

    vulpes Guest

    On Jul 3, 4:03 pm, Juha Nieminen <> wrote:
    > Chelong wrote:
    > > srand((int)time(0));

    >
    > A quick solution is to use clock() instead of time().


    Actually that's not recommended. clock() returns the number of clock
    ticks since the _start of the program_ not since epoch or whatever.
    Thus it will always give very similar values, because srand is usually
    called at the start of the program. It will even give same values
    almost always because usually the OS won't do a context switch (or any
    other memory tricks) before the srand gets called and so a constant
    number of instructions (and clock ticks) gets done before grabbing the
    clock() value.

    As Chelong says, boost::random is _the_ choice. It uses Mersenne
    Twister algorithm which is way better and faster than the basic C/C++
    rand().

    You should take care when using rand(), because some Windows machines
    let the rand() value to be just a two byte short, which sucks. It
    doesn't matter usually though. Also, you shouldn't use the same seed
    for more than one tenth or hundredth of the rand()'s granularity. So
    for a four byte rand() you shouldn't generate more than ten million
    random numbers with the same seed. This sounds pretty stupid, but many
    number-crunching programs (such as those I have to write once in a
    while) actually may use billions of random numbers. This does not
    apply to the boost::random library's Mersenne Twister as you won't
    need that many random numbers in your life as that algorithm can
    generate before the randomness breaks.
    vulpes, Jul 9, 2007
    #8
  9. Chelong

    Jim Langston Guest

    "vulpes" <> wrote in message
    news:...
    > On Jul 3, 4:03 pm, Juha Nieminen <> wrote:
    >> Chelong wrote:
    >> > srand((int)time(0));

    >>
    >> A quick solution is to use clock() instead of time().

    >
    > Actually that's not recommended. clock() returns the number of clock
    > ticks since the _start of the program_ not since epoch or whatever.
    > Thus it will always give very similar values, because srand is usually
    > called at the start of the program. It will even give same values
    > almost always because usually the OS won't do a context switch (or any
    > other memory tricks) before the srand gets called and so a constant
    > number of instructions (and clock ticks) gets done before grabbing the
    > clock() value.
    >
    > As Chelong says, boost::random is _the_ choice. It uses Mersenne
    > Twister algorithm which is way better and faster than the basic C/C++
    > rand().
    >
    > You should take care when using rand(), because some Windows machines
    > let the rand() value to be just a two byte short, which sucks. It
    > doesn't matter usually though. Also, you shouldn't use the same seed
    > for more than one tenth or hundredth of the rand()'s granularity. So
    > for a four byte rand() you shouldn't generate more than ten million
    > random numbers with the same seed. This sounds pretty stupid, but many
    > number-crunching programs (such as those I have to write once in a
    > while) actually may use billions of random numbers. This does not
    > apply to the boost::random library's Mersenne Twister as you won't
    > need that many random numbers in your life as that algorithm can
    > generate before the randomness breaks.


    It seems that time() + clock() would do the trick, no?
    Jim Langston, Jul 9, 2007
    #9
  10. Chelong

    Pete Becker Guest

    On 2007-07-09 16:28:11 -0400, vulpes <> said:

    >
    > As Chelong says, boost::random is _the_ choice. It uses Mersenne
    > Twister algorithm which is way better and faster than the basic C/C++
    > rand().


    There is no boost::random class or template. There are a handful of
    random number generators in Boost, and they've been incorporated into
    TR1. mersenne_twister is one of them. Whether it's "way better" depends
    on your application. It's certainly much bigger than the typical C
    implementation of rand, both in the size of its code and in the amount
    of data that it stores.

    >
    > You should take care when using rand(), because some Windows machines
    > let the rand() value to be just a two byte short, which sucks. It
    > doesn't matter usually though.


    Well, if it usually doesn't matter, then it doesn't categorically "suck."

    > Also, you shouldn't use the same seed
    > for more than one tenth or hundredth of the rand()'s granularity. So
    > for a four byte rand() you shouldn't generate more than ten million
    > random numbers with the same seed. This sounds pretty stupid, but many
    > number-crunching programs (such as those I have to write once in a
    > while) actually may use billions of random numbers. This does not
    > apply to the boost::random library's Mersenne Twister as you won't
    > need that many random numbers in your life as that algorithm can
    > generate before the randomness breaks.


    Okay, so you shouldn't do it, except when it's okay to do it.

    Bottom line: choosing a random number generator requires far more data
    than is present here, and sweeping generalities aren't helpful.

    --
    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
    Pete Becker, Jul 9, 2007
    #10
  11. Chelong

    James Kanze Guest

    On Jul 9, 10:28 pm, vulpes <> wrote:
    > On Jul 3, 4:03 pm, Juha Nieminen <> wrote:


    > > Chelong wrote:
    > > > srand((int)time(0));


    > > A quick solution is to use clock() instead of time().


    > Actually that's not recommended. clock() returns the number of clock
    > ticks since the _start of the program_ not since epoch or whatever.
    > Thus it will always give very similar values, because srand is usually
    > called at the start of the program. It will even give same values
    > almost always because usually the OS won't do a context switch (or any
    > other memory tricks) before the srand gets called and so a constant
    > number of instructions (and clock ticks) gets done before grabbing the
    > clock() value.


    It's worse. The start time is only "related only to the program
    invocation". At least under Solaris, the first call to clock()
    always returns 0.

    There are a number of system dependant solutions; under Unix,
    for example, you can open "/dev/random", and read a couple of
    bytes, or use gettimeofday to get the time in microseconds (but
    the actual granularity won't be that fine). Hashing in a number
    of various values, like the process id and the machine map
    address, can be used as well.

    > As Chelong says, boost::random is _the_ choice. It uses Mersenne
    > Twister algorithm which is way better and faster than the basic C/C++
    > rand().


    Boost random is a component, not a single class. You choose the
    algorithm, and all of the algorithms require a seed, so using
    Boost doesn't affect the problem the original poster had. I'm
    curious about "faster" as well. A linear congruent generator is
    just a multiplication and a modulo; the Mersenne twister seems
    to do a lot more operations than just those. So if your machine
    has good 64 bit hardware multiply and divide, the minimum
    standard generator should be a lot faster. (This will obviously
    depend on the machine, of course.)

    Independantly of the speed, of course, rand() is often poorly
    implemented, and you're better off using one of the Boost
    algorithms, all of which have specified behavior, so you can
    know what you are getting.

    > You should take care when using rand(), because some Windows machines
    > let the rand() value to be just a two byte short, which sucks.


    For historical reasons, any number of machines declare RAND_MAX
    to be 32767. For historical reasons, a lot of machines have a
    very poor rand().

    > It doesn't matter usually though. Also, you shouldn't use the
    > same seed for more than one tenth or hundredth of the rand()'s
    > granularity.


    What do you mean by granularity? Obviously, you don't want to
    use more than a small part of the generator's cycle, but it's
    fairly simple to combine generators if you need a longer cycle.
    Or use the lagged fibonacci from boost. (In practice, it
    depends on your needs. For most interactive game playing, I
    would guess that the period of any of the Boost algorithms would
    be sufficient.)

    --
    James Kanze (GABI Software) email:
    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
    James Kanze, Jul 10, 2007
    #11
  12. Chelong

    James Kanze Guest

    On Jul 9, 10:30 pm, "Jim Langston" <> wrote:
    > "vulpes" <> wrote in message
    > news:...


    [...]
    > It seems that time() + clock() would do the trick, no?


    Under Solaris, the first call to clock() always returns 0. If
    you're running on the same machine, getpid() (Unix) or
    GetCurrentProcessId() (Windows), should provide enough
    additional differentiation; if you're worried about the same
    seed on different processors, you can throw in the MAP address
    or the IP address as well. Both systems also provide the time
    with additional precision (gettimeofday(), under Unix, or
    GetSystemTime() under Windows).

    Also, I'd use some sort of hash code for combining them, and not
    just adding.

    --
    James Kanze (GABI Software) email:
    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
    James Kanze, Jul 10, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. August1
    Replies:
    4
    Views:
    7,702
    August1
    Dec 8, 2003
  2. August1
    Replies:
    0
    Views:
    7,485
    August1
    May 16, 2004
  3. Intaek LIM
    Replies:
    1
    Views:
    406
    Andreas Kahari
    Oct 31, 2003
  4. Replies:
    4
    Views:
    351
    Marcus Kwok
    Oct 19, 2005
  5. Arijit Das

    srand versus srandom - srand with random() safe?

    Arijit Das, Oct 17, 2011, in forum: C Programming
    Replies:
    12
    Views:
    2,938
    Nick Keighley
    Oct 18, 2011
Loading...

Share This Page