Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > srand(time(NULL))

Reply
Thread Tools

srand(time(NULL))

 
 
Ioannis Vranos
Guest
Posts: n/a
 
      03-10-2008
Regarding C95:


Is srand(time(NULL)); an effective solution for seeding rand(), or is
there any better approach?
 
Reply With Quote
 
 
 
 
Mark Bluemel
Guest
Posts: n/a
 
      03-10-2008
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

 
Reply With Quote
 
 
 
 
Mark Bluemel
Guest
Posts: n/a
 
      03-10-2008
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.
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      03-10-2008
Ioannis Vranos <(E-Mail Removed)> 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
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      03-10-2008
Ioannis Vranos <(E-Mail Removed)> 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 <(E-Mail Removed)>.
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[i];

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
 
Reply With Quote
 
Ioannis Vranos
Guest
Posts: n/a
 
      03-10-2008
Richard Bos wrote:
> Ioannis Vranos <(E-Mail Removed)> 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?
 
Reply With Quote
 
Ioannis Vranos
Guest
Posts: n/a
 
      03-10-2008
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.
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      03-10-2008
Ioannis Vranos <(E-Mail Removed)> wrote:

> Richard Bos wrote:
> > Ioannis Vranos <(E-Mail Removed)> 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
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      03-10-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) (Richard Bos) writes:

> Ioannis Vranos <(E-Mail Removed)> wrote:
>> Richard Bos wrote:
>> > Ioannis Vranos <(E-Mail Removed)> 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,0xa6 7f6aaa,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 1utchar(a[i&15]);break;}}}
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-10-2008
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.

--
(E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments