Question about random generator.

M

mdh

Hi Group,
Followed the faq to generate random numbers within a given range, so
used this:


# include <stdlib.h>
# define ULIMIT 100


int(........)

intarr= ( rand()/(RAND_MAX/ULIMIT+1));


Perhaps I have not run the function enough, but each time, intarr[0]
equals 0. The subsequent numbers are "random" or "psuedo-random" as I
would expect, but I cannot explain element '0'. Have I just not run it
enough? Or is there another explanation.

Thanks in advance.
 
K

Keith Thompson

mdh said:
Hi Group,
Followed the faq to generate random numbers within a given range, so
used this:


# include <stdlib.h>
# define ULIMIT 100


int(........)

intarr= ( rand()/(RAND_MAX/ULIMIT+1));


Perhaps I have not run the function enough, but each time, intarr[0]
equals 0. The subsequent numbers are "random" or "psuedo-random" as I
would expect, but I cannot explain element '0'. Have I just not run it
enough? Or is there another explanation.


The explanation is in the rest of the code, which you didn't post.

If you'll show us a complete self-contained program, we migh be able
to help. Otherwise, we can't do more than guess.
 
M

mdh

Keith said:
The explanation is in the rest of the code, which you didn't post.

If you'll show us a complete self-contained program, we migh be able
to help. Otherwise, we can't do more than guess.

Ok....I am going through K&R, and trying to get my head around Shell
Sorts. Wanted to generate random numbers for my "presorted" array,
"intarr". But just using rand() gave me such big numbers, hard to get
my head around it. Hence this formula. The rest of the function deals
with the sort, and does not effect intarr. ( I think).


#include <stdio.h>
# include <stdlib.h>
# define NELEMENTS 1000
# define UBOUND NELEMENTS-1
# define ULIMIT 100




int main (){

int intarr[NELEMENTS], v[NELEMENTS], i, j;

for (i=0; i <=UBOUND; i++)


intarr= ( rand()/(RAND_MAX/ULIMIT+1));

j=i=0;


while ( j<= UBOUND)

v[j++] = intarr[i++];
 
K

Keith Thompson

mdh said:
Keith said:
The explanation is in the rest of the code, which you didn't post.

If you'll show us a complete self-contained program, we migh be able
to help. Otherwise, we can't do more than guess.

Ok....I am going through K&R, and trying to get my head around Shell
Sorts. Wanted to generate random numbers for my "presorted" array,
"intarr". But just using rand() gave me such big numbers, hard to get
my head around it. Hence this formula. The rest of the function deals
with the sort, and does not effect intarr. ( I think).


#include <stdio.h>
# include <stdlib.h>
# define NELEMENTS 1000
# define UBOUND NELEMENTS-1
# define ULIMIT 100




int main (){

int intarr[NELEMENTS], v[NELEMENTS], i, j;

for (i=0; i <=UBOUND; i++)


intarr= ( rand()/(RAND_MAX/ULIMIT+1));

j=i=0;


while ( j<= UBOUND)

v[j++] = intarr[i++];


This is still incomplete. Where's the rest of the program?

rand() always generates the same sequence given the same starting
point. Use srand() to specify a different starting point. See the
FAQ for details. I don't know if that's the problem.
 
M

mdh

Keith said:
This is still incomplete. Where's the rest of the program?


Ok...here is the entire program. The reason I am not using a subroutine
is to be able to step through it and watch what happens...I know the
structure below is not ideal.

#include <stdio.h>
# include <stdlib.h>
# define NELEMENTS 1000
# define UBOUND NELEMENTS-1
# define ULIMIT 100


void shellsort( int v[], int n);

int main (){

int intarr[NELEMENTS], v[NELEMENTS], i, j;

for (i=0; i <=UBOUND; i++)


intarr= ( rand()/(RAND_MAX/ULIMIT+1));

j=i=0;


while ( j<= UBOUND)

v[j++] = intarr[i++];


/* shellsort(intarr2, NELEMENTS-1); */

int gap, k, l, temp, z ;

for (gap=UBOUND/2; gap>0; gap /=2)

for (k=gap; k <= UBOUND; k++)

for ( l=k-gap; l >=0 && v[l] > v[l+gap]; l -= gap) {

temp=v[l];
v[l]=v[l+gap];
v[l+gap]=temp;

}
int m;

printf("%20s %20s %20s\n\n\n", "Arr Subscript","Presorted", "Sorted");

for (z=m=0; m<=UBOUND; m++,z++)

printf("%10d %30d %20d\n", z ,intarr[m], v[m]);







return 0;
}


/************/

void shellsort( int v[], int n){

int gap, i, j, temp;

for (gap=n/2; gap>0; gap /=2)

for ( i=gap; i < n; i++)

for ( j=i-gap; j >=0 && v[j] > v[j+gap]; j -= gap) {

temp=v[j];
v[j]=v[j+gap];
v[j+gap]=temp;

}

}
 
S

santosh

mdh said:
Hi Group,
Followed the faq to generate random numbers within a given range, so
used this:


# include <stdlib.h>
# define ULIMIT 100


int(........)

intarr= ( rand()/(RAND_MAX/ULIMIT+1));


Perhaps I have not run the function enough, but each time, intarr[0]
equals 0. The subsequent numbers are "random" or "psuedo-random" as I
would expect, but I cannot explain element '0'. Have I just not run it
enough? Or is there another explanation.


It seems that that is the sequence of your particular rand()
implementation. Trying seeding rand() with srand(time(NULL)). Then see
if intarr[0] still contains a zero.
 
M

mdh

santosh said:
It seems that that is the sequence of your particular rand()
implementation. Trying seeding rand() with srand(time(NULL)). Then see
if intarr[0] still contains a zero.

Tks Santosh...I guess I am not completely familiar with the notion of
seeding rand. Is there a ref to this in the FAQ? Or, is this something
that can be explained briefly?
 
S

santosh

mdh said:
santosh said:
It seems that that is the sequence of your particular rand()
implementation. Trying seeding rand() with srand(time(NULL)). Then see
if intarr[0] still contains a zero.

Tks Santosh...I guess I am not completely familiar with the notion of
seeding rand. Is there a ref to this in the FAQ? Or, is this something
that can be explained briefly?

Look up question 13.17 at http://c-faq.com/

The idiomatic way is, as I explained previously, to pass the return
value of the time() function, to srand() after casting it to an
unsigned integer.
 
M

mdh

santosh said:
The idiomatic way is, as I explained previously, to pass the return
value of the time() function, to srand() after casting it to an
unsigned integer.

thank you Santosh.
 
R

Richard Heathfield

santosh said:
mdh said:
santosh said:
It seems that that is the sequence of your particular rand()
implementation. Trying seeding rand() with srand(time(NULL)). Then see
if intarr[0] still contains a zero.

Tks Santosh...I guess I am not completely familiar with the notion of
seeding rand. Is there a ref to this in the FAQ? Or, is this something
that can be explained briefly?

Look up question 13.17 at http://c-faq.com/

The idiomatic way is, as I explained previously, to pass the return
value of the time() function, to srand() after casting it to an
unsigned integer.

This can fail if the value returned by time() is not expressible as an
unsigned int, cast or no cast.
 
S

santosh

Richard said:
santosh said:
mdh said:
santosh wrote:

It seems that that is the sequence of your particular rand()
implementation. Trying seeding rand() with srand(time(NULL)). Then see
if intarr[0] still contains a zero.

Tks Santosh...I guess I am not completely familiar with the notion of
seeding rand. Is there a ref to this in the FAQ? Or, is this something
that can be explained briefly?

Look up question 13.17 at http://c-faq.com/

The idiomatic way is, as I explained previously, to pass the return
value of the time() function, to srand() after casting it to an
unsigned integer.

This can fail if the value returned by time() is not expressible as an
unsigned int, cast or no cast.

Yes. Thats why I provided a link to the FAQs, which, presumably, the OP
will read before writing his code.
 
M

mdh

Richard said:
This can fail if the value returned by time() is not expressible as an
unsigned int, cast or no cast.


This is what I have now used.....it seems to do the trick....is this
how others would do it?

<Same code as above>

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

for (i=0; i <=ubound; i++)

intarr= ( rand()/(RAND_MAX/ULIMIT+1));


etc etc
 
R

Richard Heathfield

santosh said:
Yes. Thats why I provided a link to the FAQs, which, presumably, the OP
will read before writing his code.

Until not so terribly long ago, a guy called Lawrence Kirby was a regular
contributor to comp.lang.c - Lawrence's knowledge of C was quite
astounding, and he was a decent bloke too. Never got into fights, never
raised a hand to anyone, just poured out his C knowledge on the group
whenever it was needed. Wonderful chap. I do hope he returns soon.

He once posted an srand-initialising routine, to maximise the entropy
available from time() without invoking potentially undefined behaviour:

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

/* Usage: srand (time_seed ()); */

/* Choose and return an initial random seed based on the current time. */

unsigned
time_seed (void)
{
time_t timeval;
unsigned char *ptr;
unsigned 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;
}
 
S

santosh

Richard said:
santosh said:
Yes. Thats why I provided a link to the FAQs, which, presumably, the OP
will read before writing his code.

Until not so terribly long ago, a guy called Lawrence Kirby was a regular
contributor to comp.lang.c - Lawrence's knowledge of C was quite
astounding, and he was a decent bloke too. Never got into fights, never
raised a hand to anyone, just poured out his C knowledge on the group
whenever it was needed. Wonderful chap. I do hope he returns soon.

He once posted an srand-initialising routine, to maximise the entropy
available from time() without invoking potentially undefined behaviour:

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

/* Usage: srand (time_seed ()); */

/* Choose and return an initial random seed based on the current time. */

unsigned
time_seed (void)
{
time_t timeval;
unsigned char *ptr;
unsigned 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;
}


Okay, it extracts timeval's component bytes, implicitly converting them
to unsigned int. Just a question. Why is 2 being added to UCHAR_MAX?
And what if sizeof (char) == sizeof (int)? Would the function be
equally useful then, as far as increasing the entropy of timeval is
concerned?
 
R

Richard Heathfield

santosh said:

<Lawrence Kirby's time_seed() function)
#include <stddef.h>
#include <time.h>
#include <limits.h>

/* Usage: srand (time_seed ()); */

/* Choose and return an initial random seed based on the current time. */

unsigned
time_seed (void)
{
time_t timeval;
unsigned char *ptr;
unsigned 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;
}


Okay, it extracts timeval's component bytes, implicitly converting them
to unsigned int. Just a question. Why is 2 being added to UCHAR_MAX?


To give you a number of the form 2^n + 1, which, empirically speaking, is
quite a good form to use when hashing a series of bytes into an individual
value.
And what if sizeof (char) == sizeof (int)?

In such a circumstance, admittedly, the hashing is less good! :) In such a
case, you might want to multiply by, say, (UCHAR_MAX - 1) / 2 + 2 instead.
Or maybe even (UCHAR_MAX - 3) / 4 + 2.
 
B

Ben Pfaff

Richard Heathfield said:
santosh said:

<Lawrence Kirby's time_seed() function)

To give you a number of the form 2^n + 1, which, empirically speaking, is
quite a good form to use when hashing a series of bytes into an individual
value.

In particular, n is usually 8, so UCHAR_MAX + 2 is usually 257,
which is prime.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top