BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Rand()

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Non-Technical)
View previous topic :: View next topic  
Author Message
LarryJ
Guest





PostPosted: Wed Dec 06, 2006 8:32 pm    Post subject: Rand() Reply with quote



Below are two setups for creating a random number between 1 and 54. Are
these the two setups the same or does the, % 55; have an effect on how the
Rand() function select the number?


Randomize();
while(Num1==0){
Num1 = rand() % 55;
}

Randomize();
while(Num1<1 || Num1>54){
Num1 = rand();
}

Thanks
Larry Johnson
Back to top
Bruce Salzman
Guest





PostPosted: Wed Dec 06, 2006 8:46 pm    Post subject: Re: Rand() Reply with quote



"LarryJ" <LarryJ33 (AT) austin (DOT) rr.com> wrote in message
news:4576d447$1 (AT) newsgroups (DOT) borland.com...
Quote:
Below are two setups for creating a random number between 1 and 54.
Are these the two setups the same or does the, % 55; have an effect
on how the Rand() function select the number?


They are both inefficient ways of producing a number between 1 and 54,
inclusive. Better would be

Num1 = random(54) + 1;

--
Bruce
Back to top
Alan Bellingham
Guest





PostPosted: Wed Dec 06, 2006 8:58 pm    Post subject: Re: Rand() Reply with quote



"LarryJ" <LarryJ33 (AT) austin (DOT) rr.com> wrote:

Quote:
Below are two setups for creating a random number between 1 and 54. Are
these the two setups the same or does the, % 55; have an effect on how the
Rand() function select the number?

No, they are not the same.

Quote:
Randomize();
while(Num1==0){
Num1 = rand() % 55;
}

This calls rand(), and then wraps the result to a number in the range 0
to 54. If the result is zero, then it retries.

It will have a very slight tendency to generate lower numbers rather
than higher numbers, since the input to the modulo operator will be in
the range 0 to RAND_MAX, and I'd be very surprised if RAND_MAX is an
exact multiple of 55. (Given that BCB5 defines it as 0x7FFFU!)

It will loop about 1 time in 55.

Quote:
Randomize();
while(Num1<1 || Num1>54){
Num1 = rand();
}

This will keep generating the next number in the sequence till it finds
one that fits. It doesn't suffer the slight bias of the first option,
but it will call rand() rather more times. Hundreds more times.

The first option is closer to being correct, but there's an obviously
stupid bit - the code

Randomize();
Num1 = 1 + (rand() % 54);

would produce a number in the range 1 - 54 inclusive, without any
looping, and with no worse a bias than previous. If you wanted to remove
the bias, then

while (Num1 > (54 * 606)) // last multiple before RAND_MAX (32767)
{
Num1 = rand();
}
Num1 = 1 + (Num1 % 54);

You could probably write a quick little function to do the clipping,
modulus and addition for you, given a desired minimum and maximum value.

Alan Bellingham
--
ACCU Conference: 11-14 April 2007 - Paramount Oxford Hotel
Back to top
Alan Bellingham
Guest





PostPosted: Wed Dec 06, 2006 9:04 pm    Post subject: Re: Rand() Reply with quote

" Bruce Salzman" <bruce (AT) nospam (DOT) org> wrote:

Quote:
They are both inefficient ways of producing a number between 1 and 54,
inclusive. Better would be

Num1 = random(54) + 1;

which translates to

Num1 = int(_lrand() % 54) + 1;

Indeed, that'd do. (Slight result bias excluded, and if you're that
worried about slight bias, you'll be using a better random number
generator. It's going to be pretty negligible when using _lrand().)

Alan Bellingham
--
ACCU Conference: 11-14 April 2007 - Paramount Oxford Hotel
Back to top
LarryJ
Guest





PostPosted: Thu Dec 07, 2006 3:37 pm    Post subject: Re: Rand() Reply with quote

I am using BCB6.0 and I am looking for a way to generate a true random
number between 1 and 54. I have been disappointed with the results I am
getting from the built in random number generators such as using randomize()
with rand() or random(). When I analyze all the results after running these
functions 100,000 times I am seeing that the results tend to select some
numbers an overwhelming number of times and other numbers almost never.
Theoretically each number should selected a number of times that is close to
the mean. I have been looking for a true random number generation code but
have only found some old code in Basic. Is there any good random number
generation code available in C++?

Thanks
Larry Johnson
Back to top
Bruce Larrabee
Guest





PostPosted: Thu Dec 07, 2006 5:14 pm    Post subject: Re: Rand() Reply with quote

Hi Larry,

This from 'Numerical Recipes in C':

In C, if you multiply two unsigned long int integers on a machine with a 32-bit
long integer representation, the value returned is the low-order 32 bits of the
true 64-bit product. If we now choose m = 232, the mod in equation (7.1.1)
is free, and we have simply Ij+1 = aIj + c.
Knuth suggests a = 1664525 as a suitable multiplier for this value of m.
H.W. Lewis has conducted extensive tests of this value of a with c = 1013904223,
which is a prime close to (p5 - 2)m. The resulting in-line generator
(we will call it ranqd1) is simply:

unsigned long idum;

idum = 1664525L*idum + 1013904223L;

This is about as good as any 32-bit linear congruential generator,
entirely adequate for many uses. And, with only a single multiply and add,
it is very fast.

To check whether your machine has the desired integer properties, see if you can
generate the following sequence of 32-bit values (given here in hex): 00000000,
3C6EF35F, 47502932, D1CCF6E9, AAF95334, 6252E503, 9F2EC686, 57FE6C2D, A3D95FA8,
81FDBEE7, 94F0AF1A, CBF633B1.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I haven't tried this..

But I have used this:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)

Minimal random number generator of Park and Miller with Bays-Durham shuffle
and added safeguards. Returns a uniform random deviate between 0.0 and 1.0
(exclusive of the endpointvalues).
Call with idum a negative integer to initialize; thereafter, do not alter idum
between successive deviates in a sequence. RNMX should approximate the largest
floating value that is less than 1.

float ran1(long *idum)
{
int j;
long k;
static long iy=0;
static long iv[NTAB];
float temp;

if (*idum <= 0 || !iy)
{
// Initialize

if (-(*idum) < 1)
{
*idum=1; Be sure to prevent idum = 0.
}
else
{
*idum = -(*idum);
}

for (j=NTAB+7;j>=0;j--)
{
// Load the shuffle table (after 8 warm-ups).

k=(*idum)/IQ;

*idum=IA*(*idum-k*IQ)-IR*k;

if (*idum < 0)
{
*idum += IM;
}

if (j < NTAB)
{
iv[j] = *idum;
}
}

iy=iv[0];
}

k=(*idum)/IQ; // Start here when not initializing.

// Compute idum=(IA*idum) % IM without overflows
// by Schrage's method.

*idum=IA*(*idum-k*IQ)-IR*k;

if (*idum < 0)
{
*idum += IM;
}

j=iy/NDIV; // Will be in the range 0..NTAB-1.

// Output previously stored value and refill the
// suffle table.

iy=iv[j];

iv[j] = *idum;

if ((temp=AM*iy) > RNMX)
{
return RNMX;
}
else
{
return temp;
}
}

HTH,

Bruce
Back to top
Richard Kavanagh
Guest





PostPosted: Sat Dec 09, 2006 11:37 pm    Post subject: Re: Rand() Reply with quote

This is one of many.
Richard

long FSeed = 17; // pick a big number. prime might be good idea. run
tests.
long Rand()
{
// m = 2147483647 = 2^31 - 1; a = 16807;
// 127773 = m div a; 2836 = m mod a

long hi = FSeed / 127773L; // integer division
long lo = FSeed - hi * 127773L; // modulo
FSeed = 16807 * lo - 2836 * hi;
if (FSeed <= 0)
FSeed += 2147483647L;
return FSeed;
}
Back to top
Thorsten Kettner
Guest





PostPosted: Wed Dec 13, 2006 4:16 pm    Post subject: Re: Rand() Reply with quote

"LarryJ" <LarryJ33 (AT) austin (DOT) rr.com> wrote:
Quote:
I am using BCB6.0 and I am looking for a way to generate a
true random number between 1 and 54. I have been disappointed
with the results I am getting from the built in random number
generators such as using randomize() with rand() or random().
When I analyze all the results after running these functions
100,000 times I am seeing that the results tend to select some
numbers an overwhelming number of times and other numbers
almost never.
Theoretically each number should selected a number of times
that is close to the mean.

Strange. I have BCB 6 Ent Build 10.166 and random works like a
charm. With only 100,000 loops I get counts of about 1750 to
1950. With 10,000,000 loops I get counts of 184000 to 186500.
Doesn't look to bad to me. Maybe there is an error in your code?
Mine looks thus:

int arr[54] = { 0 };
randomize();
for(int i = 0; i < 10000000; ++i)
++arr[random(54)];
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Non-Technical) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.