time and srand

Discussion in 'C Programming' started by conrad, Dec 20, 2007.

  1. conrad

    conrad Guest

    What kind of problems could arise if
    one were to not cast the value of time()
    to unsigned int? What are the sections
    in the standard that provide the reasoning
    of any claims against such a practice?

    --
    conrad
    conrad, Dec 20, 2007
    #1
    1. Advertising

  2. conrad

    santosh Guest

    conrad wrote:

    > What kind of problems could arise if
    > one were to not cast the value of time()
    > to unsigned int? What are the sections
    > in the standard that provide the reasoning
    > of any claims against such a practice?


    The cast is recommended since there is no implicit conversion between
    unsigned and time_t. The C standard simply says that time_t is an
    arithmetic type. It could be an integer or floating point type.
    Therefore an explicit cast is usual when using a time_t value as seed
    for srand.
    santosh, Dec 20, 2007
    #2
    1. Advertising

  3. santosh said:

    > conrad wrote:
    >
    >> What kind of problems could arise if
    >> one were to not cast the value of time()
    >> to unsigned int? What are the sections
    >> in the standard that provide the reasoning
    >> of any claims against such a practice?

    >
    > The cast is recommended


    No, it isn't.

    See
    http://groups.google.com/group/comp...0/f9316d326af97ad6?lnk=st&q=#f9316d326af97ad6

    or, if that doesn't work and you trust me enough, see
    http://tinyurl.com/2ur3c3

    --
    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, Dec 20, 2007
    #3
  4. santosh <> writes:
    > conrad wrote:
    >> What kind of problems could arise if
    >> one were to not cast the value of time()
    >> to unsigned int? What are the sections
    >> in the standard that provide the reasoning
    >> of any claims against such a practice?

    >
    > The cast is recommended since there is no implicit conversion between
    > unsigned and time_t. The C standard simply says that time_t is an
    > arithmetic type. It could be an integer or floating point type.
    > Therefore an explicit cast is usual when using a time_t value as seed
    > for srand.


    Yes, there is an implicit conversion from unsigned to time_t, as there
    is between any two arithmetic types.

    This:
    srand(time(NULL));
    and this:
    srand((unsigned)time(NULL));
    are equivalent, assuming you have the required "#include <time.h>".
    Since the cast doesn't buy you anything, you might as well leave it
    out.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 20, 2007
    #4
  5. conrad

    James Kuyper Guest

    conrad wrote:
    > What kind of problems could arise if
    > one were to not cast the value of time()
    > to unsigned int? What are the sections
    > in the standard that provide the reasoning
    > of any claims against such a practice?


    I can't see any plausible problems with not casting the value of time()
    to an unsigned int.

    I do see possible problems from casting it to unsigned int:

    1. If time_t is a signed integer type, the conversion will not be value
    preserving for negative values.

    2. If time_t is a type with a maximum greater than UINT_MAX, the
    conversion will lose the high-order bits.

    3. If time_t is a floating point type, the conversion will loose you the
    fractional part,

    4. If time_t is an imaginary type, the conversion will loose 100% of the
    information.

    Who suggested to you that conversion to unsigned int was the proper
    thing to do, and what reasons did they give?
    James Kuyper, Dec 20, 2007
    #5
  6. conrad

    santosh Guest

    James Kuyper wrote:

    > conrad wrote:
    >> What kind of problems could arise if
    >> one were to not cast the value of time()
    >> to unsigned int? What are the sections
    >> in the standard that provide the reasoning
    >> of any claims against such a practice?

    >
    > I can't see any plausible problems with not casting the value of
    > time() to an unsigned int.
    >
    > I do see possible problems from casting it to unsigned int:


    <snip>

    In light of your, Keith's, and Richard's reply I apologise to the OP for
    incorrect advice.
    santosh, Dec 20, 2007
    #6
  7. James Kuyper <> writes:
    > conrad wrote:
    >> What kind of problems could arise if
    >> one were to not cast the value of time()
    >> to unsigned int? What are the sections
    >> in the standard that provide the reasoning
    >> of any claims against such a practice?

    >
    > I can't see any plausible problems with not casting the value of
    > time() to an unsigned int.


    Agreed.

    > I do see possible problems from casting it to unsigned int:
    >
    > 1. If time_t is a signed integer type, the conversion will not be
    > value preserving for negative values.
    >
    > 2. If time_t is a type with a maximum greater than UINT_MAX, the
    > conversion will lose the high-order bits.
    >
    > 3. If time_t is a floating point type, the conversion will loose you
    > the fractional part,
    >
    > 4. If time_t is an imaginary type, the conversion will loose 100% of
    > the information.
    >
    > Who suggested to you that conversion to unsigned int was the proper
    > thing to do, and what reasons did they give?


    The context, I think was
    srand(time(NULL));
    Since srand's argument is of type unsigned int, the conversion will
    happen with or without a cast.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 20, 2007
    #7
  8. conrad

    Guest

    Keith Thompson wrote:
    > James Kuyper <> writes:

    ....
    > > Who suggested to you that conversion to unsigned int was the proper
    > > thing to do, and what reasons did they give?

    >
    > The context, I think was
    > srand(time(NULL));
    > Since srand's argument is of type unsigned int, the conversion will
    > happen with or without a cast.


    Depending upon the implementation-specific time representation used
    for time_t, that expression might generate only a small number of
    different seed values, or it might generate seed values that change
    excessively slowly with time. What you typically need in that context
    is an expression that generates a different seed value each time you
    run the program, and has a roughly equal chance of generating every
    permitted seed value.

    To minimize dependence upon the representation of time_t, I'd
    recommend something like this:

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

    srand(fmod(difftime(0, time(NULL), UINT_MAX+1.0));

    That will use different seed values at the rate of 1/second, which
    should be good enough for many purposes.
    , Dec 20, 2007
    #8
  9. conrad

    Guest

    On Dec 20, 2:06 pm, wrote:
    > Keith Thompson wrote:
    > > James Kuyper <> writes:

    > ...
    > > > Who suggested to you that conversion to unsigned int was the proper
    > > > thing to do, and what reasons did they give?

    >
    > > The context, I think was
    > > srand(time(NULL));
    > > Since srand's argument is of type unsigned int, the conversion will
    > > happen with or without a cast.

    >
    > Depending upon the implementation-specific time representation used
    > for time_t, that expression might generate only a small number of
    > different seed values, or it might generate seed values that change
    > excessively slowly with time. What you typically need in that context
    > is an expression that generates a different seed value each time you
    > run the program, and has a roughly equal chance of generating every
    > permitted seed value.
    >
    > To minimize dependence upon the representation of time_t, I'd
    > recommend something like this:
    >
    > #include <limits.h>
    > #include <stdlib.h>
    > #include <math.h>
    > #include <time.h>
    >
    > srand(fmod(difftime(0, time(NULL), UINT_MAX+1.0));
    >
    > That will use different seed values at the rate of 1/second, which
    > should be good enough for many purposes.


    I was thinking too hard; the fmod() is unnecessary, of course.
    , Dec 20, 2007
    #9
  10. said:

    <snip>

    > To minimize dependence upon the representation of time_t, I'd
    > recommend something like this:
    >
    > #include <limits.h>
    > #include <stdlib.h>
    > #include <math.h>
    > #include <time.h>
    >
    > srand(fmod(difftime(0, time(NULL), UINT_MAX+1.0));


    Lawrence Kirby once proposed the following alternative, which works very
    nicely:

    #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;


    }

    --
    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, Dec 20, 2007
    #10
  11. conrad

    cr88192 Guest

    <> wrote in message
    news:...
    > Keith Thompson wrote:
    >> James Kuyper <> writes:

    > ...
    >> > Who suggested to you that conversion to unsigned int was the proper
    >> > thing to do, and what reasons did they give?

    >>
    >> The context, I think was
    >> srand(time(NULL));
    >> Since srand's argument is of type unsigned int, the conversion will
    >> happen with or without a cast.

    >
    > Depending upon the implementation-specific time representation used
    > for time_t, that expression might generate only a small number of
    > different seed values, or it might generate seed values that change
    > excessively slowly with time. What you typically need in that context
    > is an expression that generates a different seed value each time you
    > run the program, and has a roughly equal chance of generating every
    > permitted seed value.
    >
    > To minimize dependence upon the representation of time_t, I'd
    > recommend something like this:
    >
    > #include <limits.h>
    > #include <stdlib.h>
    > #include <math.h>
    > #include <time.h>
    >
    > srand(fmod(difftime(0, time(NULL), UINT_MAX+1.0));
    >
    > That will use different seed values at the rate of 1/second, which
    > should be good enough for many purposes.


    one option I have used:
    implement a custom prng, with a larger internal state, for example, 4096
    bits (reason: rand does not necissarily have all that large of an internal
    state, and is thus not really good for some uses);
    the initialization function can load the seed from a file, use the 'time'
    trick, rehash the seed or similar, and store it back out to the file (thus
    each run hopefully adding a little more entropy).

    if done well, with any luck, this gives at least some semblence of
    randomness.

    rand is useful for some things (where the actual randomness isn't all that
    important, or only applies to a small range).

    but, when using it for some other things, for example, generating largish
    presumably unique values (GUID-like values, ...) one hopes for something
    hopefully a little more 'random'.

    for example, if it only has about 32 or 48 bits of entropy, what good is it
    to try to generate , say, 96 bit unique values. there will be, at most (and
    probably much less) 2^32 or 2^48 different values.

    a slightly larger entropy, say, 2^4096, is a little more sane for this kind
    of use.

    or such...


    now, here is another possibly interesting (mostly hypothetical) problem:
    open-source copy protection.

    goal: a copy protection scheme which will still work, even when the user has
    full ability to look at, modify, and recompile the source (and, thus, it
    can't be based on obscurity, or something which the user can simply bypass
    or comment out).

    I have some possible ideas here, but I will keep them to myself...
    cr88192, Dec 20, 2007
    #11
  12. conrad

    Jack Klein Guest

    On Thu, 20 Dec 2007 12:45:31 GMT, James Kuyper
    <> wrote in comp.lang.c:

    > conrad wrote:
    > > What kind of problems could arise if
    > > one were to not cast the value of time()
    > > to unsigned int? What are the sections
    > > in the standard that provide the reasoning
    > > of any claims against such a practice?

    >
    > I can't see any plausible problems with not casting the value of time()
    > to an unsigned int.
    >
    > I do see possible problems from casting it to unsigned int:


    No problems that do not occur without the cast to unsigned int, given
    a prototype for srand() is in scope.

    > 1. If time_t is a signed integer type, the conversion will not be value
    > preserving for negative values.
    >
    > 2. If time_t is a type with a maximum greater than UINT_MAX, the
    > conversion will lose the high-order bits.
    >
    > 3. If time_t is a floating point type, the conversion will loose you the
    > fractional part,


    If time_t is a floating point type and the integral part of the value
    is greater than UINT_MAX or less than 0, the conversion will generate
    undefined behavior. With or without a cast.

    > 4. If time_t is an imaginary type, the conversion will loose 100% of the
    > information.


    What exactly is an imaginary type in C? They only exist as part of a
    _Complex float, double, or long double. They no more exist in
    isolation than do quarks.

    If time_t is a _Complex type, the behavior is undefined with or
    without the cast, because the standard does not define such a
    conversion.

    If a _Complex type is converted via an intermediary (real float,
    double, or long double), then the imaginary part is simply discarded,
    and the behavior is undefined if the real part of the _Complex is
    outside the range of the destination floating point type.

    If that succeeds, the resulting float can be converted, with or
    without cast, to unsigned int as an argument to srand(). Again
    producing undefined behavior if the integer part of the floating point
    type is negative or greater than UINT_MAX.

    > Who suggested to you that conversion to unsigned int was the proper
    > thing to do, and what reasons did they give?


    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Dec 21, 2007
    #12
  13. Jack Klein <> writes:
    > On Thu, 20 Dec 2007 12:45:31 GMT, James Kuyper
    > <> wrote in comp.lang.c:

    [...]
    >> 4. If time_t is an imaginary type, the conversion will loose 100% of the
    >> information.

    >
    > What exactly is an imaginary type in C? They only exist as part of a
    > _Complex float, double, or long double. They no more exist in
    > isolation than do quarks.

    [...]

    _Imaginary float, _Imaginary double, or _Imaginary long double.

    See C99 Annex G (which is optional).

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 21, 2007
    #13
  14. conrad

    James Kuyper Guest

    Jack Klein wrote:
    > On Thu, 20 Dec 2007 12:45:31 GMT, James Kuyper
    > <> wrote in comp.lang.c:
    >
    >> conrad wrote:
    >>> What kind of problems could arise if
    >>> one were to not cast the value of time()
    >>> to unsigned int? What are the sections
    >>> in the standard that provide the reasoning
    >>> of any claims against such a practice?

    >> I can't see any plausible problems with not casting the value of time()
    >> to an unsigned int.
    >>
    >> I do see possible problems from casting it to unsigned int:

    >
    > No problems that do not occur without the cast to unsigned int, given
    > a prototype for srand() is in scope.
    >
    >> 1. If time_t is a signed integer type, the conversion will not be value
    >> preserving for negative values.
    >>
    >> 2. If time_t is a type with a maximum greater than UINT_MAX, the
    >> conversion will lose the high-order bits.
    >>
    >> 3. If time_t is a floating point type, the conversion will loose you the
    >> fractional part,

    >
    > If time_t is a floating point type and the integral part of the value
    > is greater than UINT_MAX or less than 0, the conversion will generate
    > undefined behavior. With or without a cast.
    >
    >> 4. If time_t is an imaginary type, the conversion will loose 100% of the
    >> information.

    >
    > What exactly is an imaginary type in C? They only exist as part of a
    > _Complex float, double, or long double. They no more exist in
    > isolation than do quarks.


    Yes, they've isolated the _Imaginary type. The "double _Imaginary" type
    is a type with the same size as 'double', which can only represent
    values with a real component of 0, just as ordinary 'double' can only
    represent values with an imaginary component of 0. I can't imagine any
    good reason for defining time_t as an imaginary type, except that it is
    permitted for a conforming implementation of C, and it breaks a lot of
    code that seems perfectly harmless because it wasn't written with that
    possibility in mind, which could be useful for teaching purposes, if
    nothing else. The really nasty possibility is that clock_t is imaginary,
    which would require that CLOCKS_PER_SEC must also be imaginary.

    > If time_t is a _Complex type, the behavior is undefined with or
    > without the cast, because the standard does not define such a
    > conversion.


    When time_t is a complex type, the following rules apply:

    6.2.5p17: " ... The integer and real floating types are collectively
    called real types."

    Key point: integer types are real types, as far as the C standard is
    concerned. That means that the citations below apply when the
    destination is an integer type.

    6.3.1.7p2:
    "When a value of complex type is converted to a real type, the imaginary
    part of the complex value is discarded and the value of the real part is
    converted according to the conversion rules for the corresponding real
    type."

    > If a _Complex type is converted via an intermediary (real float,


    You don't need to explicitly specify an intermediary; the sections
    listed above describe a direct conversion, that works pretty much as you
    describe for the indirect conversion.

    However, if time_t were an imaginary type, the rules from Annex G4.2p1
    apply: "When a value of imaginary type is converted to a real type other
    than _Bool,324) the result is a positive zero."
    James Kuyper, Dec 21, 2007
    #14
  15. conrad

    Guest

    Jack Klein wrote:
    > On Thu, 20 Dec 2007 12:45:31 GMT, James Kuyper
    > <> wrote in comp.lang.c:

    ....
    > > 3. If time_t is a floating point type, the conversion will loose you the
    > > fractional part,

    >
    > If time_t is a floating point type and the integral part of the value
    > is greater than UINT_MAX or less than 0, the conversion will generate
    > undefined behavior. With or without a cast.


    For some reason I remembered incorrectly that the modulus rules for
    conversion to unsigned types applied to floating point sources as
    well. Since you are correct, that means that the fmod() in my other
    message was indeed necessary.
    , Dec 21, 2007
    #15
  16. conrad

    cr88192 Guest

    "Keith Thompson" <> wrote in message
    news:...
    > Jack Klein <> writes:
    >> On Thu, 20 Dec 2007 12:45:31 GMT, James Kuyper
    >> <> wrote in comp.lang.c:

    > [...]
    >>> 4. If time_t is an imaginary type, the conversion will loose 100% of the
    >>> information.

    >>
    >> What exactly is an imaginary type in C? They only exist as part of a
    >> _Complex float, double, or long double. They no more exist in
    >> isolation than do quarks.

    > [...]
    >
    > _Imaginary float, _Imaginary double, or _Imaginary long double.
    >
    > See C99 Annex G (which is optional).
    >


    and, a few of us were lazy and ended up internally aliasing _Imaginary to
    _Complex...

    actually, at first I had implemented them as such, later noticing that GCC
    had only _Complex, and thus I lacked some motivation on this front, and
    later on _Complex effectively assimilated _Imaginary.


    now, something even more weird:
    in my upper compiler, since _Complex only applies to float types, and
    'unsigned' only really applies to integer types, I ended up using the same
    modifier for both (in this case, a flag).

    so, in this case:
    unsigned float f;
    and:
    float _Complex f;

    come out as equivalent...


    however, in the lower compiler, each type effectively has a unique type, so
    there is no such aliasing at this level.


    > --
    > Keith Thompson (The_Other_Keith) <>
    > Looking for software development work in the San Diego area.
    > "We must do something. This is something. Therefore, we must do this."
    > -- Antony Jay and Jonathan Lynn, "Yes Minister"
    cr88192, Dec 21, 2007
    #16
  17. conrad

    Thad Smith Guest

    Open source copy protection

    Followups set to comp.programming.

    cr88192 wrote:

    > now, here is another possibly interesting (mostly hypothetical) problem:
    > open-source copy protection.
    >
    > goal: a copy protection scheme which will still work, even when the user has
    > full ability to look at, modify, and recompile the source (and, thus, it
    > can't be based on obscurity, or something which the user can simply bypass
    > or comment out).


    What is the goal of a copy protection scheme when the user has the ability
    to look at, modify, and recompile the source? What, specifically, is being
    protected from what?

    > I have some possible ideas here, but I will keep them to myself...


    You can use a public-key-based signature to demonstrate that some
    particular person has approved a particular version. That doesn't prevent
    copying, though.

    --
    Thad
    Thad Smith, Dec 27, 2007
    #17
  18. conrad

    Army1987 Guest

    James Kuyper wrote:

    > 4. If time_t is an imaginary type, the conversion will loose 100% of the
    > information.


    That's an implementation I'd like to have!

    --
    Army1987 (Replace "NOSPAM" with "email")
    Army1987, Dec 30, 2007
    #18
  19. conrad

    Geoff Guest

    On Sun, 30 Dec 2007 16:40:31 +0000 (UTC), Army1987
    <> wrote:

    >James Kuyper wrote:
    >
    >> 4. If time_t is an imaginary type, the conversion will loose 100% of the
    >> information.

    >
    >That's an implementation I'd like to have!


    For all the language pedantry in this group, you would think they
    would be better spellers.

    lose, not loose.

    Simple mnemonic:

    To lose is lost.
    Too loose is a noose.
    Geoff, Dec 30, 2007
    #19
  20. conrad

    James Kuyper Guest

    Geoff wrote:
    > On Sun, 30 Dec 2007 16:40:31 +0000 (UTC), Army1987
    > <> wrote:
    >
    >> James Kuyper wrote:
    >>
    >>> 4. If time_t is an imaginary type, the conversion will loose 100% of the
    >>> information.

    >> That's an implementation I'd like to have!

    >
    > For all the language pedantry in this group, you would think they
    > would be better spellers.


    Being pedantic about other people's mistakes doesn't mean that I don't
    make mistakes of my own; it just means that it's annoying when I
    discover that I've made one. Still, I prefer to know about my mistakes,
    rather than remaining ignorant of them.
    James Kuyper, Dec 31, 2007
    #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:
    416
    Andreas Kahari
    Oct 31, 2003
  2. Ioannis Vranos

    srand(time(0))

    Ioannis Vranos, Mar 10, 2008, in forum: C++
    Replies:
    15
    Views:
    16,100
    James Kanze
    Mar 11, 2008
  3. Ioannis Vranos

    srand(time(NULL))

    Ioannis Vranos, Mar 10, 2008, in forum: C Programming
    Replies:
    41
    Views:
    30,558
    Mark McIntyre
    Mar 12, 2008
  4. red floyd

    Re: srand(time(0))

    red floyd, Oct 27, 2008, in forum: C++
    Replies:
    0
    Views:
    462
    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,001
    Nick Keighley
    Oct 18, 2011
Loading...

Share This Page