srand(time(NULL))

Discussion in 'C Programming' started by Ioannis Vranos, Mar 10, 2008.

  1. Regarding C95:


    Is srand(time(NULL)); an effective solution for seeding rand(), or is
    there any better approach?
     
    Ioannis Vranos, Mar 10, 2008
    #1
    1. Advertising

  2. Ioannis Vranos

    Mark Bluemel Guest

    Ioannis Vranos wrote:
    > Regarding C95:
    >
    >
    > Is srand(time(NULL)); an effective solution for seeding rand(), or is
    > there any better approach?


    There's some discussion in this area in section 13 of the C FAQ
    (http://www.c-faq.com). Try Question 13.17
     
    Mark Bluemel, Mar 10, 2008
    #2
    1. Advertising

  3. Ioannis Vranos

    Mark Bluemel Guest

    Ioannis Vranos wrote:
    > Regarding C95:
    >
    >
    > Is srand(time(NULL)); an effective solution for seeding rand(), or is
    > there any better approach?


    In addition to my previous reply, Google gives loads of hits for
    "seeding a random number generator", many of which look helpful.
     
    Mark Bluemel, Mar 10, 2008
    #3
  4. Ioannis Vranos

    Richard Bos Guest

    Ioannis Vranos <> wrote:

    > Is srand(time(NULL)); an effective solution for seeding rand(),


    Unless your time_t is a floating point type and the current time is
    larger than UINT_MAX (not likely, in particular the first part);
    as long as you don't call it more than once every time_t tick;
    and as long as your rand() is at least of semi-reasonable quality (i.e.,
    successive seeds don't lead to similar series), it's fine.

    Richard
     
    Richard Bos, Mar 10, 2008
    #4
  5. Ioannis Vranos

    Ben Pfaff Guest

    Ioannis Vranos <> writes:

    > Is srand(time(NULL)); an effective solution for seeding rand(), or is
    > there any better approach?


    By default, the C random number generator produces the same
    sequence every time the program is run. In order to generate
    different sequences, it has to be "seeded" using srand() with a
    unique value. The function below to do this is carefully
    designed. It uses time() to obtain the current time; the
    alternative clock() is a poor choice because it measures CPU time
    used, which is often more or less constant among runs. The
    actual value of a time_t is not portable, so it computes a "hash"
    of the bytes in it using a multiply-and-add technique. The
    factor used for multiplication normally comes out as 257, a prime
    and therefore a good candidate.

    References: Knuth, _The Art of Computer Programming, Vol. 2:
    Seminumerical Algorithms_, section 3.2.1; Aho, Sethi, and Ullman,
    _Compilers: Principles, Techniques, and Tools_, section 7.6.

    #include <limits.h>
    #include <stdlib.h>
    #include <time.h>

    /* Choose and return an initial random seed based on the current time.
    Based on code by Lawrence Kirby <>.
    Usage: srand (time_seed ()); */
    unsigned
    time_seed (void)
    {
    time_t timeval; /* Current time. */
    unsigned char *ptr; /* Type punned pointed into timeval. */
    unsigned seed; /* Generated seed. */
    size_t i;

    timeval = time (NULL);
    ptr = (unsigned char *) &timeval;

    seed = 0;
    for (i = 0; i < sizeof timeval; i++)
    seed = seed * (UCHAR_MAX + 2u) + ptr;

    return seed;
    }

    --
    "It wouldn't be a new C standard if it didn't give a
    new meaning to the word `static'."
    --Peter Seebach on C99
     
    Ben Pfaff, Mar 10, 2008
    #5
  6. Richard Bos wrote:
    > Ioannis Vranos <> wrote:
    >
    >> Is srand(time(NULL)); an effective solution for seeding rand(),

    >
    > Unless your time_t is a floating point type



    The function prototype of srand() is

    void srand(unsigned int seed);


    Whatever time_t is, isn't there an implicit conversion to unsigned?



    > and the current time is
    > larger than UINT_MAX (not likely, in particular the first part);



    If the value is larger than UINT_MAX, doesn't the argument seed just
    wrap around?
     
    Ioannis Vranos, Mar 10, 2008
    #6
  7. The FAQ mentions:

    #include <stdlib.h>
    #include <time.h>

    srand((unsigned int)time((time_t *)NULL));


    I think the casting of NULL to "time_t *" is unnecessary in C, since
    NULL can be assigned to any pointer type without casting (also the
    conversion of void * to whatever_type * is implicit).


    Also since the srand() function protype is

    void srand(unsigned int seed);


    I think the casting of the return value of time() to unsigned int is
    unnecessary, since the return value is implicitly converted to the
    unsigned int argument.
     
    Ioannis Vranos, Mar 10, 2008
    #7
  8. Ioannis Vranos

    Richard Bos Guest

    Ioannis Vranos <> wrote:

    > Richard Bos wrote:
    > > Ioannis Vranos <> wrote:
    > >
    > >> Is srand(time(NULL)); an effective solution for seeding rand(),

    > >
    > > Unless your time_t is a floating point type

    >
    > The function prototype of srand() is
    >
    > void srand(unsigned int seed);
    >
    > Whatever time_t is, isn't there an implicit conversion to unsigned?


    Yes. But the conversion of a floating point value to an integral type
    causes UB if that value, rounded down, would not fit into the integral
    type - even if it's an unsigned type.

    > > and the current time is
    > > larger than UINT_MAX (not likely, in particular the first part);

    >
    > If the value is larger than UINT_MAX, doesn't the argument seed just
    > wrap around?


    You'd think so, but no, not on conversion from a floating point value.

    At least, not in C90. I haven't looked up whether this remains true in
    C99.

    Richard
     
    Richard Bos, Mar 10, 2008
    #8
  9. Ioannis Vranos

    Ben Pfaff Guest

    (Richard Bos) writes:

    > Ioannis Vranos <> wrote:
    >> Richard Bos wrote:
    >> > Ioannis Vranos <> wrote:
    >> >> Is srand(time(NULL)); an effective solution for seeding rand(),
    >> > Unless your time_t is a floating point type

    >> The function prototype of srand() is
    >>
    >> void srand(unsigned int seed);
    >>
    >> Whatever time_t is, isn't there an implicit conversion to unsigned?

    > Yes. But the conversion of a floating point value to an integral type
    > causes UB if that value, rounded down, would not fit into the integral
    > type - even if it's an unsigned type.


    Additionally, a floating point time value may not be useful as a
    random seed, for example if the time value is always between 0
    and 1. (I am not aware of any systems that do this.)
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Mar 10, 2008
    #9
  10. Ioannis Vranos

    Eric Sosman Guest

    Ioannis Vranos wrote:
    > The FAQ mentions:
    >
    > #include <stdlib.h>
    > #include <time.h>
    >
    > srand((unsigned int)time((time_t *)NULL));
    >
    >
    > I think the casting of NULL to "time_t *" is unnecessary in C, since
    > NULL can be assigned to any pointer type without casting (also the
    > conversion of void * to whatever_type * is implicit).
    >
    >
    > Also since the srand() function protype is
    >
    > void srand(unsigned int seed);
    >
    >
    > I think the casting of the return value of time() to unsigned int is
    > unnecessary, since the return value is implicitly converted to the
    > unsigned int argument.


    "Unnecessary" is not always the same as "undesirable" --
    do you use indentation to indicate block nesting? -- and the
    question of whether to use or omit these casts is in some
    degree a matter of taste. Myself, I'd omit them. Yet the
    Ten Commandments For C Programmers takes the opposite view
    (Third Commandment), so I am probably in a state of sin.

    --
     
    Eric Sosman, Mar 10, 2008
    #10
  11. Ben Pfaff wrote:
    > (Richard Bos) writes:
    >
    >> Ioannis Vranos <> wrote:
    >>> Richard Bos wrote:
    >>>> Ioannis Vranos <> wrote:
    >>>>> Is srand(time(NULL)); an effective solution for seeding rand(),
    >>>> Unless your time_t is a floating point type
    >>> The function prototype of srand() is
    >>>
    >>> void srand(unsigned int seed);
    >>>
    >>> Whatever time_t is, isn't there an implicit conversion to unsigned?

    >> Yes. But the conversion of a floating point value to an integral type
    >> causes UB if that value, rounded down, would not fit into the integral
    >> type - even if it's an unsigned type.

    >
    > Additionally, a floating point time value may not be useful as a
    > random seed, for example if the time value is always between 0
    > and 1. (I am not aware of any systems that do this.)



    Also I assume in the floating point case, casting to unsigned is
    needless, right?
     
    Ioannis Vranos, Mar 10, 2008
    #11
  12. Eric Sosman <> writes:
    > Ioannis Vranos wrote:
    >> The FAQ mentions:
    >>
    >> #include <stdlib.h>
    >> #include <time.h>
    >>
    >> srand((unsigned int)time((time_t *)NULL));
    >>
    >>
    >> I think the casting of NULL to "time_t *" is unnecessary in C, since
    >> NULL can be assigned to any pointer type without casting (also the
    >> conversion of void * to whatever_type * is implicit).
    >>
    >>
    >> Also since the srand() function protype is
    >>
    >> void srand(unsigned int seed);
    >>
    >>
    >> I think the casting of the return value of time() to unsigned int is
    >> unnecessary, since the return value is implicitly converted to the
    >> unsigned int argument.

    >
    > "Unnecessary" is not always the same as "undesirable" --
    > do you use indentation to indicate block nesting? -- and the
    > question of whether to use or omit these casts is in some
    > degree a matter of taste. Myself, I'd omit them. Yet the
    > Ten Commandments For C Programmers takes the opposite view
    > (Third Commandment), so I am probably in a state of sin.


    Reference: <http://www.lysator.liu.se/c/ten-commandments.html>,
    written by Henry Spencer.

    The original version of this fine document was written, I believe,
    before the existence of ANSI C. The Third Commandment is:

    Thou shalt cast all function arguments to the expected type if
    they are not of that type already, even when thou art convinced
    that this is unnecessary, lest they take cruel vengeance upon thee
    when thou least expect it.

    The newer annotation reads, in part:

    It may be thought that the radical new blessing of ``prototypes''
    might eliminate the need for caution about argument types. Not so,
    brethren. Firstly, when confronted with the twisted strangeness of
    variable numbers of arguments, the problem returns... and he who
    has not kept his faith strong by repeated practice shall surely
    fall to this subtle trap. Secondly, the wise men have observed
    that reliance on prototypes doth open many doors to strange
    errors, and some indeed had hoped that prototypes would be decreed
    for purposes of error checking but would not cause implicit
    conversions. Lastly, reliance on prototypes causeth great
    difficulty in the Real World today, when many cling to the old
    ways and the old compilers out of desire or necessity, and no man
    knoweth what machine his code may be asked to run on tomorrow.

    This was good advice *at the time it was written*. Today, C compilers
    that don't support prototypes are vanishingly rare, and this advice is
    IMHO obsolete. You still need to be careful when calling variadic
    functions; for example, when passing a pointer to printf with the "%p"
    format, you should cast it to void*. (Quibbles: If it's already
    void*, you don't need to cast it; if it's char*, you can probably get
    away without casting it, but you should anyway; if it's a function
    pointer, you can't portably print it with "%p" with or without a
    cast.)

    I'd say the 4th and 9th commandments are similarly obsolete. The 8th
    (which mandates K&R brace style) is something that I *wish* everyone
    obeyed, but if you're working under a coding standard that requires
    some other style, it's more important to be consistent with that, and
    with the existing code, than to use the (IMHO better) K&R style. The
    only thing worse than code that uses an ugly brace style is code that
    uses a mixture of different brace styles.

    The remaining Commandments are still good advice today.

    In particular, the Eight Commandment includes one of the best pieces
    of programming advice I've ever seen, even if you disagree with the
    premise that K&R defined the One True Brace Style:

    ... for thy creativity is better used in solving problems than in
    creating beautiful new impediments to understanding.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 10, 2008
    #12
  13. Keith Thompson said:

    <snip>
    >
    > I'd say [Henry Spencer's] 4th and 9th commandments are similarly
    > obsolete. The 8th
    > (which mandates K&R brace style) is something that I *wish* everyone
    > obeyed,


    Fortunately, your wishing well is broken. K&R style is *dire*.

    Cue the Brace Wars.

    <snip>

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Mar 10, 2008
    #13
  14. Ioannis Vranos <> writes:
    > Ben Pfaff wrote:
    >> (Richard Bos) writes:
    >>
    >>> Ioannis Vranos <> wrote:
    >>>> Richard Bos wrote:
    >>>>> Ioannis Vranos <> wrote:
    >>>>>> Is srand(time(NULL)); an effective solution for seeding rand(),
    >>>>> Unless your time_t is a floating point type
    >>>> The function prototype of srand() is
    >>>>
    >>>> void srand(unsigned int seed);
    >>>>
    >>>> Whatever time_t is, isn't there an implicit conversion to unsigned?
    >>> Yes. But the conversion of a floating point value to an integral type
    >>> causes UB if that value, rounded down, would not fit into the integral
    >>> type - even if it's an unsigned type.

    >>
    >> Additionally, a floating point time value may not be useful as a
    >> random seed, for example if the time value is always between 0
    >> and 1. (I am not aware of any systems that do this.)

    >
    > Also I assume in the floating point case, casting to unsigned is
    > needless, right?


    Correct; the conversion is implicit for any arithmetic type (which
    time_t is guaranteed to be). If time_t is a floating-point type, then
    other problems appear: if the result of time() doesn't vary outside a
    small range, then you won't get much variation in seed values, and if
    it can go outside the range 0 .. UINT_MAX, the behavior of the
    conversion can be undefined.

    In theory, you could even have problems with an integer time_t.
    Imagine that unsigned int is 32 bits, and time_t is a 64-bit integer
    type whose high-order 32 bits represent time in seconds and whose
    low-order 32 bits represent fractions of a second. Imagine further
    that the underlying system clock can only represent whole seconds, so
    the low-order 32 bits are always 0. Then converting *any* time_t
    value returned by time() to unsigned int will yield 0.

    Ben Pfaff's solution (treating the time_t result as an array of
    unsigned char and hashing it) avoids all these problems, none of which
    are likely but all of which are allowed by the standard.

    In practice, using srand(time(NULL)) is likely to be good enough for a
    quick-and-dirty program, and is unlikely to break in any of the above
    described ways on any system you're likely to run into in real life.
    On the other hand, the implementation-provided rand() function is
    typically not very good; if you want *good* random numbers, you should
    use some other technique. <HANDWAVE>See the literature for
    details.</HANDWAVE>

    Incidentally, I've e-mailed Steve Summit (the FAQ maintainer) about this;
    he says:

    Say, you're right. That's a last vestige of my PDP-11/V7/K&R C
    days -- I thought I'd stamped those all out.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 10, 2008
    #14
  15. Richard Heathfield <> writes:
    > Keith Thompson said:
    > <snip>
    >>
    >> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
    >> obsolete. The 8th
    >> (which mandates K&R brace style) is something that I *wish* everyone
    >> obeyed,

    >
    > Fortunately, your wishing well is broken. K&R style is *dire*.
    >
    > Cue the Brace Wars.
    >
    > <snip>


    NOOOOOOOOOOO!!!!!!!

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 10, 2008
    #15
  16. Keith Thompson said:

    <snip>

    > Ben Pfaff's solution (treating the time_t result as an array of
    > unsigned char and hashing it) avoids all these problems,


    As Ben would be the first to acknowledge, that was actually Lawrence
    Kirby's solution.

    <snip>

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Mar 10, 2008
    #16
  17. Ioannis Vranos

    Ben Pfaff Guest

    Ioannis Vranos <> writes:

    > Ben Pfaff wrote:
    >> (Richard Bos) writes:
    >>
    >>> Ioannis Vranos <> wrote:
    >>>> Richard Bos wrote:
    >>>>> Ioannis Vranos <> wrote:
    >>>>>> Is srand(time(NULL)); an effective solution for seeding rand(),
    >>>>> Unless your time_t is a floating point type
    >>>> The function prototype of srand() is
    >>>>
    >>>> void srand(unsigned int seed);
    >>>>
    >>>> Whatever time_t is, isn't there an implicit conversion to unsigned?
    >>> Yes. But the conversion of a floating point value to an integral type
    >>> causes UB if that value, rounded down, would not fit into the integral
    >>> type - even if it's an unsigned type.

    >>
    >> Additionally, a floating point time value may not be useful as a
    >> random seed, for example if the time value is always between 0
    >> and 1. (I am not aware of any systems that do this.)

    >
    > Also I assume in the floating point case, casting to unsigned is
    > needless, right?


    Casting a floating-point value to unsigned int will have the same
    effect as allowing it to be implicitly converted to unsigned int
    by omitting the cast when a prototype of srand() is visible, so a
    cast to unsigned int would not be useful.
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Mar 10, 2008
    #17
  18. Ioannis Vranos

    Ben Pfaff Guest

    Keith Thompson <> writes:

    > Incidentally, I've e-mailed Steve Summit (the FAQ maintainer) about this;
    > he says:
    >
    > Say, you're right. That's a last vestige of my PDP-11/V7/K&R C
    > days -- I thought I'd stamped those all out.


    It's very odd to see the cast in the online FAQ, because the text
    version that I keep on my local file system, which says it was
    last modified February 7, 1999, omits the cast. Odd that it was
    apparently (re?)introduced after that.

    I should really update my local copy.
    --
    Ben Pfaff
    http://benpfaff.org
     
    Ben Pfaff, Mar 10, 2008
    #18
  19. Ioannis Vranos

    Morris Dovey Guest

    Richard wrote:
    >
    > Richard Heathfield <> writes:
    >
    > > Keith Thompson said:
    > >
    > > <snip>
    > >>
    > >> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
    > >> obsolete. The 8th
    > >> (which mandates K&R brace style) is something that I *wish* everyone
    > >> obeyed,

    > >
    > > Fortunately, your wishing well is broken. K&R style is *dire*.
    > >
    > > Cue the Brace Wars.
    > >
    > > <snip>

    >
    > K&R style is easily the most maintainable and easiest on the eye I have
    > ever used. It just "makes sense. header, body, footer. e.g
    >
    > if(expr){
    > expr;
    > }


    Now loading trebuchet with barn waste...

    --
    Morris Dovey
    DeSoto Solar
    DeSoto, Iowa USA
    http://www.iedu.com/DeSoto/
     
    Morris Dovey, Mar 10, 2008
    #19
  20. On 10 Mar 2008 at 16:42, Richard Heathfield wrote:
    > Keith Thompson said:
    >
    ><snip>
    >>
    >> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
    >> obsolete. The 8th
    >> (which mandates K&R brace style) is something that I *wish* everyone
    >> obeyed,

    >
    > Fortunately, your wishing well is broken. K&R style is *dire*.
    >
    > Cue the Brace Wars.


    The familiar Heathfield combination of minimal taste and maximal
    polemic...
     
    Antoninus Twink, Mar 10, 2008
    #20
    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. Intaek LIM
    Replies:
    1
    Views:
    417
    Andreas Kahari
    Oct 31, 2003
  2. conrad

    time and srand

    conrad, Dec 20, 2007, in forum: C Programming
    Replies:
    20
    Views:
    1,136
    merl the perl
    Jan 2, 2008
  3. Ioannis Vranos

    srand(time(0))

    Ioannis Vranos, Mar 10, 2008, in forum: C++
    Replies:
    15
    Views:
    16,108
    James Kanze
    Mar 11, 2008
  4. red floyd

    Re: srand(time(0))

    red floyd, Oct 27, 2008, in forum: C++
    Replies:
    0
    Views:
    463
    red floyd
    Oct 27, 2008
  5. Arijit Das

    srand versus srandom - srand with random() safe?

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

Share This Page