 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
LarryJ Guest
|
Posted: Wed Dec 06, 2006 8:32 pm Post subject: Rand() |
|
|
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
|
Posted: Wed Dec 06, 2006 8:46 pm Post subject: Re: Rand() |
|
|
"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
|
Posted: Wed Dec 06, 2006 8:58 pm Post subject: Re: Rand() |
|
|
"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
|
Posted: Wed Dec 06, 2006 9:04 pm Post subject: Re: Rand() |
|
|
" 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
|
Posted: Thu Dec 07, 2006 3:37 pm Post subject: Re: Rand() |
|
|
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
|
Posted: Thu Dec 07, 2006 5:14 pm Post subject: Re: Rand() |
|
|
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
|
Posted: Sat Dec 09, 2006 11:37 pm Post subject: Re: Rand() |
|
|
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
|
Posted: Wed Dec 13, 2006 4:16 pm Post subject: Re: Rand() |
|
|
"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 |
|
 |
|
|
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
|
|