N groups of random numbers with different ranges

M

Masud

hi,
for a test i want to generate different random numbers between
different ranges in a single loop. I tried to solve in the following
way but it always profile same value. I am looking for suggestion in
this regard.

#include <cstdlib>
#include <time.h>
#include<iostream.h>

int main()
{
int i,j;
for(i=0;i<n;i++) //N set of rendom numbers
{
j=randomize(1,5); // first number
cout<<j;
j=randomize(1,6); // second number and so on..
cout<<j;
}
}

int randomize(int LOW,int HIGH)
{
int value;
time_t seconds;// Declare variable to hold seconds on
//clock.
time(&seconds);//Get value from system clock and place in
//seconds variable.
srand((unsigned int) seconds);//Convert seconds to a
//unsigned integer.
value = rand() % (HIGH - LOW + 1) + LOW;//Get the random
//value between LOW and HIGH
return value;
}
 
K

Keith Thompson

Masud said:
for a test i want to generate different random numbers between
different ranges in a single loop. I tried to solve in the following
way but it always profile same value. I am looking for suggestion in
this regard.

#include <cstdlib>

Make this '#include said:
#include <time.h>
#include<iostream.h>

Wrong language; that's C++. Use '#include said:
int main()
{
int i,j;
for(i=0;i<n;i++) //N set of rendom numbers

There's no declaration of 'n'. This obviously isn't your actual code.
{
j=randomize(1,5); // first number

There's been no declaration of 'randomize' yet. You can probably get
away with this, but you should always declare functions before calling
them. In this case, you could just move the definition of randomize
above the definition of main.
cout<<j;
j=randomize(1,6); // second number and so on..
cout<<j;
}
}

int randomize(int LOW,int HIGH)
{
int value;
time_t seconds;// Declare variable to hold seconds on
//clock.
time(&seconds);//Get value from system clock and place in
//seconds variable.
srand((unsigned int) seconds);//Convert seconds to a
//unsigned integer.
value = rand() % (HIGH - LOW + 1) + LOW;//Get the random
//value between LOW and HIGH
return value;
}

Unless you have a special reason to do otherwise, call srand() just
once at the beginning of your program; then you can call rand()
multiple times. You're probably getting the same result each time
because your program takes less than a second to run, so you get the
same result from time() each time.

The comp.lang.c FAQ is at <http://www.c-faq.com/>. Questions 13.15
through 13.21 deal with random numbers.
 
M

Martin Ambuhl

Masud said:
hi,
for a test i want to generate different random numbers between
different ranges in a single loop. I tried to solve in the following
way but it always profile same value. I am looking for suggestion in
this regard.

#include <cstdlib>
#include <time.h>
#include<iostream.h>

One of these headers is a C++ header and not a C header.
The C++ <cstdlib> header corresponds to the C header <stdlib.h>
One of these headers is superficially a C++ header, but isn't, and is
not a C header.
There is no C header corresponding to the C++ header <iostream>.
Notice the name of the C++ header.
One of these headers is a C header, the use of which is deprecated for C++:
The C header <time.h> has a corresponding C++ header <ctime>

These suggest that you want to post to <and not to
<C++ and C are different languages. When you do post
to comp.lang.c++, make your headers
#include <cstdlib>
#include <ctime>
#include <iostream>
Do them the favor, which you did not do for us, of checking earlier
posts and their FAQ. You also need to learn to properly specify the
namespace for standard identifiers, whether explicitly on each use or
which a "using" clause, unless you want to be laughed out of court.

Further, calling srand() in your function randomize is a logical error.
Call srand() once before using rand(). Subsequent calls of srand() are
very unlikely to do what you want.

Do not use the '%' operator to reduce the range of random numbers. It
is a gross error, even with a good pseudo-random number generator. If
you had done comp.lang.c the courtesy of following the newsgroup for
even one day before posting you would know this already, as well as
knowing where to find why it is an error and what to do about it. But,
sure, being rude is a sign of your grandeur as a programmer.
 
A

Army1987

hi,
for a test i want to generate different random numbers between
different ranges in a single loop. I tried to solve in the following
way but it always profile same value. I am looking for suggestion in
this regard.

#include <cstdlib>
This is a C++ header. In C it is called said:
#include <time.h>
#include<iostream.h>
There is no such header in C. For C++, go to comp.lang.c++.
For C, use <stdio.h>
(anyway, the answer to your question is the same in both
languages, so I will answer here)
int main()
{
int i,j;
for(i=0;i<n;i++) //N set of rendom numbers
{
j=randomize(1,5); // first number
cout<<j; In C, use printf("%d", j)
j=randomize(1,6); // second number and so on..
cout<<j;
Sure you don't want any whitespace?
}
}

int randomize(int LOW,int HIGH)
Traditionally, UPPERCASE names are used for preprocessor macros.
The compiler doesn't care, but the reader (including yourself) can
find it helpful to determine whether something is a macro at a
glance.
{
int value;
time_t seconds;// Declare variable to hold seconds on
//clock.
time(&seconds);//Get value from system clock and place in
//seconds variable.
srand((unsigned int) seconds);//Convert seconds to a
//unsigned integer.
<OT> You included <cstdlib>, not <stdlib.h>, so you must use
std::srand (or include a using std::srand; or using namespace std;
somewhere). said:
value = rand() % (HIGH - LOW + 1) + LOW;//Get the random
//value between LOW and HIGH
See www.c-faq.com, question 13.15 onwards. In theory, this is
correct (provided HIGH - LOW + 1 is much less than RAND_MAX,
otherwise it is biased), but with many implementations of rand()
it is very poor.
 
A

Army1987

Masud wrote: [...]
#include <cstdlib>
#include <time.h>
#include<iostream.h>
[...]
There is no C header corresponding to the C++ header <iostream>.
Notice the name of the C++ header.
<ot> IIRC, <iostream.h> is a deprecated C++ header which also
declares identifiers in the unnamed namespace (e.g. cout as well
as std::cout, etc.). </ot>
 
K

Keith Thompson

Martin Ambuhl said:
Do not use the '%' operator to reduce the range of random numbers. It
is a gross error, even with a good pseudo-random number generator.
[...]

Is that true? It seems to me that with a sufficiently good PRNG,
using the '%' operator should yield good results (ignoring the bias
introduced if the range is not a factor of RAND_MAX+1). Using '%' is
a bad idea because the lower bits provided by some PRNGs are poor.
 
D

Default User

Army1987 said:
Masud wrote: [...]
#include <cstdlib>
#include <time.h>
#include<iostream.h>
[...]
There is no C header corresponding to the C++ header <iostream>.
Notice the name of the C++ header.
<ot> IIRC, <iostream.h> is a deprecated C++ header which also
declares identifiers in the unnamed namespace (e.g. cout as well
as std::cout, etc.). </ot>

No, it is not. A deprecated header (or anything else) is one that is
standard but discouraged from use. <iostream.h> is not a standard
header in C++ at all.




Brian
 
C

CBFalconer

Default said:
Army1987 said:
Masud wrote: [...]
#include <cstdlib>
#include <time.h>
#include<iostream.h> [...]
There is no C header corresponding to the C++ header <iostream>.
Notice the name of the C++ header.

<ot> IIRC, <iostream.h> is a deprecated C++ header which also
declares identifiers in the unnamed namespace (e.g. cout as well
as std::cout, etc.). </ot>

No, it is not. A deprecated header (or anything else) is one that is
standard but discouraged from use. <iostream.h> is not a standard
header in C++ at all.

And it certainly is not known in C.
 
A

Army1987

Martin Ambuhl said:
Do not use the '%' operator to reduce the range of random numbers. It
is a gross error, even with a good pseudo-random number generator.
[...]

Is that true? It seems to me that with a sufficiently good PRNG,
using the '%' operator should yield good results (ignoring the bias
introduced if the range is not a factor of RAND_MAX+1). Using '%' is
a bad idea because the lower bits provided by some PRNGs are poor.

I piped a program writing various sizes, up to 256 MB, of the
lowest byte of rand() (i.e.
for (i=0; i < size; i++)
putchar(rand() & 0xFF);
) into ent (http://www.fourmilab.ch/random/), and it didn't find
anything particular (i.e. most times I got that "Chi-squared would
randomly exceed this xx% of times" with xx between 25 and 75; also
the serial correlation coefficient was very close to zero).
(I didn't try that on Windows, I'll try when I have some spare
time.)
 
M

Martin Ambuhl

Keith said:
Martin Ambuhl said:
Do not use the '%' operator to reduce the range of random numbers. It
is a gross error, even with a good pseudo-random number generator.
[...]

Is that true? It seems to me that with a sufficiently good PRNG,
using the '%' operator should yield good results (ignoring the bias
introduced if the range is not a factor of RAND_MAX+1). Using '%' is
a bad idea because the lower bits provided by some PRNGs are poor.

Why should I ignore the introduction of bias? Simply to declare that
what is a bad idea when I recognize why it is a bad idea is not one when
I ignore that reason?

What other things do you ignore the bad features of? Ignoring the
possible results of a gunshot wound it is not a bad idea to shoot
yourself in the head.
 
K

Keith Thompson

Martin Ambuhl said:
Keith said:
Martin Ambuhl said:
Do not use the '%' operator to reduce the range of random numbers. It
is a gross error, even with a good pseudo-random number generator.
[...]
Is that true? It seems to me that with a sufficiently good PRNG,
using the '%' operator should yield good results (ignoring the bias
introduced if the range is not a factor of RAND_MAX+1). Using '%' is
a bad idea because the lower bits provided by some PRNGs are poor.

Why should I ignore the introduction of bias? Simply to declare that
what is a bad idea when I recognize why it is a bad idea is not one
when I ignore that reason?
[...]

*If* you have a sufficiently good PRNG, such that the high-order and
low-order bits of the results are well behaved, then the 'rand() % N'
and '(int)((double)rand() / ((double)RAND_MAX + 1) * N)' (quoted from
the FAQ) both suffer from a bias. And in both cases, a similar
solution applies: discard rand() results exceeding a certain
threshhold, so that the range of rand() results being used is a
multiple of the length of the desired range.

On the other hand, I see that the bias does work differently in the
two cases. Even assuming "good" results from rand(), the results of
'rand() % N' are biased in a way that skews the mean result (larger
numbers are rarer); using the other formula, some results are still
relatively rare, but they're scattered through the desired range.

So yes, there is a significant difference in the effect of the bias
(sorry I missed that), but the same solution can be used in both
cases.
 
T

Thad Smith

Army1987 said:
I piped a program writing various sizes, up to 256 MB, of the
lowest byte of rand() (i.e.
for (i=0; i < size; i++)
putchar(rand() & 0xFF);
) into ent (http://www.fourmilab.ch/random/), and it didn't find
anything particular (i.e. most times I got that "Chi-squared would
randomly exceed this xx% of times" with xx between 25 and 75; also
the serial correlation coefficient was very close to zero).

Without knowing the particular compiler and library, this means that
there exists at least one rand() implementation that has reasonably good
low-order bits. Good. It's too bad that it isn't guaranteed.
 
A

Army1987

Martin Ambuhl said:
Do not use the '%' operator to reduce the range of random numbers. It
is a gross error, even with a good pseudo-random number generator.
[...]

Is that true? It seems to me that with a sufficiently good PRNG,
using the '%' operator should yield good results (ignoring the bias
introduced if the range is not a factor of RAND_MAX+1). Using '%' is
a bad idea because the lower bits provided by some PRNGs are poor.

I piped a program writing various sizes, up to 256 MB, of the
lowest byte of rand() (i.e.
for (i=0; i < size; i++)
putchar(rand() & 0xFF);
) into ent (http://www.fourmilab.ch/random/), and it didn't find
anything particular (i.e. most times I got that "Chi-squared would
randomly exceed this xx% of times" with xx between 25 and 75; also
the serial correlation coefficient was very close to zero).
(I didn't try that on Windows, I'll try when I have some spare
time.)
With Microsoft Visual Studio 2005 Express:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define SIZE /* see below */
int main(void)
{
size_t n = SIZE;
FILE *out = fopen("rnd.dat", "wb");
if (out == NULL) { perror("fopen"); exit(EXIT_FAILURE); }
srand(time(NULL));
while (n--)
putc(rand() & 0xFF, out); /* CHAR_BIT == 8 */
if (fclose(out) != 0) { perror("fclose"); exit(EXIT_FAILURE); }
return 0;
}

Test: SIZE: Chi square: Serial corr. coefficient:
1 256 264.00 (50%) 0.016030
2 256 286.00 (10%) -0.009120
3 256 260.00 (50%) -0.215230
4 64KB 242.59 (50%) 0.001587
5 64KB 246.53 (50%) -0.003934
6 64KB 231.28 (75%) -0.005520
7 16MB 0.00 (99.99%) 0.000011
(All the values occurred exactly 65536 times; other two tests with
this SIZE gave identical results, except for the Monte Carlo value
for Pi.)

With Microsoft Visual Studio 2005 Express: #include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define SIZE 256
int main(void)
{
size_t n = SIZE;
FILE *out = fopen("rnd.dat", "wb");
if (out == NULL) { perror("fopen"); exit(EXIT_FAILURE); }
srand(time(NULL));
while (n--)
putc(rand() >> 7, out); /* CHAR_BIT == 8, RAND_MAX = 0x7fff */
if (fclose(out) != 0) { perror("fclose"); exit(EXIT_FAILURE); }
return 0;
}

Test: SIZE: Chi square: Serial corr. coefficient:
1 256 266.00 (50%) -0.104760
2 256 260.00 (50%) -0.017179
3 256 280.00 (25%) -0.007335
4 64KB 249.76 (50%) -0.003254
5 64KB 251.86 (50%) -0.002133
6 64KB 242.18 (50%) 0.001661
7 16MB 257.22 (50%) 0.000057
8 16MB 255.54 (50%) -0.000184
9 16MB 253.16 (50%) -0.000410

I haven't saved the results anywhere, but with Ubuntu 6.10,
gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5),
libc6 version 2.4-1ubuntu12, I recall that there were no obvious
differences between rand() & 0xFF and rand >> 15 (RAND_MAX is
2147483647 here).
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top