Thread View: comp.sys.amiga.tech
11 messages
11 total messages
Started by David Thiele
Mon, 03 Dec 1990 23:20
rand() within a range.
Author: David Thiele
Date: Mon, 03 Dec 1990 23:20
Date: Mon, 03 Dec 1990 23:20
21 lines
739 bytes
739 bytes
Is there a way to generate random numbers within a certain range in
Lattice C??. Ive done it with the following code but it's not very
elegant (or fast!),
Random(range,seed)
int range,seed;
{
srand(seed);
if range = 0
return(0);
else{
do
seed = rand() / 10000000;
while (seed >= range);
return(seed);
}
}
urrgghh! help
Dave
Re: rand() within a range.
Author: Dolf Grunbauer
Date: Wed, 05 Dec 1990 07:43
Date: Wed, 05 Dec 1990 07:43
47 lines
1584 bytes
1584 bytes
In article <666@sheoak.bcae.oz> 737104@sheoak.bcae.oz (David Thiele) writes:
>Is there a way to generate random numbers within a certain range in
>Lattice C??. Ive done it with the following code but it's not very
>elegant (or fast!),
>
>Random(range,seed)
>int range,seed;
>{
> srand(seed);
> if range = 0
> return(0);
> else{
> do
> seed = rand() / 10000000;
> while (seed >= range);
> return(seed);
> }
>}
>
How about:
Random(range,seed)
int range,seed;
{
srand(seed);
if range = 0
return(0);
else return (((seed = rand()) / 10000000) % range);
}
By the way: why do you want to set seed explicitly before each rand call ?
Propably what will do also is:
Random(range)
int range;
{
if range = 0
return(0);
else return (rand() % range);
}
and call 'srand' only in some initialisation function or main.
--
_ _
/ U | Dolf Grunbauer Tel: +31 55 433233 Internet dolf@idca.tds.philips.nl
/__'< Philips Information Systems UUCP ...!mcsun!philapd!dolf
88 |_\ If you are granted one wish do you know what to wish for right now ?
Re: rand() within a range.
Author: Henrik Clausen
Date: Wed, 05 Dec 1990 16:31
Date: Wed, 05 Dec 1990 16:31
27 lines
1233 bytes
1233 bytes
In article <666@sheoak.bcae.oz>, David Thiele writes:
> Is there a way to generate random numbers within a certain range in
> Lattice C??. Ive done it with the following code but it's not very
> elegant (or fast!).
You said it :-)
Try something like:
int Random(int Range)
{
return((int)(Range * drand48()));
}
Add offsets at your desire. Seed from the timer with srand48().
drand48() returns a double, and is supposed to be quite good.
BTW, this stuff is in your manual.
-Henrik
| Henrik Clausen, Graffiti Data | If the Doors of Perception where cleansed, |
| ...{pyramid|rutgers}!cbmvax! | Man would see Reality as it is - Infinite. |
\______cbmehq!adspdk!hclausen___|_________________________________W. Blake___/
Re: rand() within a range.
Author: Aaron Friesen
Date: Wed, 05 Dec 1990 23:50
Date: Wed, 05 Dec 1990 23:50
13 lines
806 bytes
806 bytes
sheoak.bcae.oz (David Thiele) / 4:20 pm Dec 3, 1990 / > Is there a way to generate random numbers within a certain range in > Lattice C??. Ive done it with the following code but it's not very > elegant (or fast!), [ Code Deleted... ] Simply taking rand() % range or something similar should give you what you want. This will be fast and about as "random" as the code you are currently using.
Re: rand() within a range.
Author: Kent Paul Dolan
Date: Thu, 06 Dec 1990 03:31
Date: Thu, 06 Dec 1990 03:31
88 lines
3646 bytes
3646 bytes
dolf@idca.tds.philips.nl (Dolf Grunbauer) writes:
> 737104@sheoak.bcae.oz (David Thiele) writes:
>> Is there a way to generate random numbers within a certain range in
>> Lattice C??. Ive done it with the following code but it's not very
>> elegant (or fast!),
> By the way: why do you want to set seed explicitly before each rand
> call ? Probably what will do also is:
> Random(range)
> int range;
> {
> if range = 0
> return(0);
> else return (rand() % range);
> }
> and call 'srand' only in some initialisation function or main.
Nope. You don't want to do that; it gives you a biased sample. To see
the worst case, suppose, where MAXINT is the largest possible output of
rand(), that range is approximately 2*MAXINT/3. Then you're going to
get about twice as many samples in the interval from zero to range/2 -1,
as in range/2 to range -1.
In psuedocode, you want:
#define MAXINT /* as whatever 2^31-1 is, assuming 32 bit integers */
Random(int range)
{
int limit, work1, work2, work3;
/*
Goal: Use as much of the possible returned range 0 to MAXINT as possible
(to minimize the number of wasted, expensive calls to rand()), without
biasing the sample.
Method: Find the biggest number of copies of 0 to range - 1 that will
fit in 0 to MAXINT; this will cover some, perhaps equal, interval 0 to
limit. If the call to rand() falls in 0 to limit, take the modulus with
range as the returned value. If not, throw away the result and try
again.
Discussion: It is desired that the value returned fall in the interval 0
to range - 1. What you want to know is how many copies of range will fit
in the interval 0 to MAXINT, or, more important, 1 to MAXINT + 1, so we
can divide to get the answer. This gets messy because you can't
represent MAXINT + 1 directly, and range might be an exact divisor of
MAXINT + 1.
*/
work1 = MAXINT/range; /* integer number of ranges that fit in MAXINT */
/* in case what was left, + 1, will hold one more copy of range */
work2 = (MAXINT - (work1 * range) + 1) / range ;
/* the "-1" has to go here to avoid overflow in the next calculation */
/* in case range is an exact divisor of MAXINT + 1 */
limit = range * work1 - 1;
/* add in zero or one more range interval */
limit = limit + range * work2;
/* limit is now the biggest usable return value from rand() */
while ((work3 = rand()) > limit) /* iterate*/ ;
return (work3 % range);
}
If only one value of range is being used, or if the programmer is
willing to do the work in the calling routine for each different value,
the calculation of limit should be moved out to the calling routine and
the calculated value passed in for efficiency. You still have to do the
seed call to srand() once somewhere, preferably near the top of your
main routine.
If that constitutes code (doubtful) then it is public domain. The idea
is yours in any case, it sure isn't original with me. Forgive bugs, I
haven't been well enough to light off a compiler since June. Modulo
possible bugs, that is the "standard" way to do the job right.
Kent, the man from xanth.
<xanthian@Zorch.SF-Bay.ORG> <xanthian@well.sf.ca.us>
Re: rand() within a range.
Author: Narciso Jaramillo
Date: Thu, 06 Dec 1990 17:26
Date: Thu, 06 Dec 1990 17:26
38 lines
2098 bytes
2098 bytes
In article <1990Dec6.033145.22855@zorch.SF-Bay.ORG> xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes: dolf@idca.tds.philips.nl (Dolf Grunbauer) writes: > 737104@sheoak.bcae.oz (David Thiele) writes: >> Is there a way to generate random numbers within a certain range in >> Lattice C??. Ive done it with the following code but it's not very >> elegant (or fast!), > return (rand() % range); Nope. You don't want to do that; it gives you a biased sample. To see the worst case, suppose, where MAXINT is the largest possible output of rand(), that range is approximately 2*MAXINT/3. Then you're going to get about twice as many samples in the interval from zero to range/2 -1, as in range/2 to range -1. If you're willing to do some floating-point arithmetic, you can also do return ((int)floor((double)(rand())/MAXINT * high)); or return ((int)floor(drand48() * high)); Since rand() returns values that are (presumably evenly) distributed over the range [0, MAXINT), (double)(rand())/MAXINT should return floating point values that are evenly distributed over the range [0.0, 1.0). Since drand48() also returns values in [0.0, 1.0), both of these should return unbiased values in the range [0, high). Slightly expensive because of the floating-point operations, but you don't have to go through the (admittedly fast, though not necessarily faster) contortions of Kent's algorithm. nj
Re: rand() within a range.
Author: Dan Barrett
Date: Fri, 07 Dec 1990 21:41
Date: Fri, 07 Dec 1990 21:41
47 lines
2036 bytes
2036 bytes
I tried e-mail but it bounced.
In article <666@sheoak.bcae.oz> 737104@sheoak.bcae.oz (David Thiele) writes:
>Is there a way to generate random numbers within a certain range in
>Lattice C??
It can be done in ANY language -- there is a mathematical formula
for it. All you need is a function Rand() that returns a random real number
between 0 and 1 (not including 1). This is commonly supplied by your
compiler company.
To generate a random integer between integers A and B, with A < B:
(1) Figure out the distance between A and B:
distance = B - A + 1;
(2) Multiply a random number by the distance, and truncate the
remainder. This gives you a random integer between 0 and
(distance - 1):
first = floor(distance * Rand());
(3) Now increase this number by A, to give you an integer between
A and (A + distance - 1). But remember:
A + distance - 1
= A + (B - A + 1) - 1
= B
So you have a random integer between A and B:
answer = first + A;
Here is the final formula:
answer = floor((B - A + 1) * Rand()) + A;
Dan
//////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
| Dan Barrett - Systems Administrator, Computer Science Department |
| The Johns Hopkins University, 34th and Charles Sts., Baltimore, MD 21218 |
| INTERNET: barrett@cs.jhu.edu | |
| COMPUSERVE: >internet:barrett@cs.jhu.edu | UUCP: barrett@jhunix.UUCP |
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////////
Re: rand() within a range.
Author: Andrew Phillips
Date: Tue, 11 Dec 1990 06:15
Date: Tue, 11 Dec 1990 06:15
38 lines
1833 bytes
1833 bytes
In article <540@ssp9.idca.tds.philips.nl> dolf@idca.tds.philips.nl (Dolf Grunbauer) writes:
>In article <666@sheoak.bcae.oz> 737104@sheoak.bcae.oz (David Thiele) writes:
>>Is there a way to generate random numbers within a certain range in
>>Lattice C??. ...
>
>...
>Random(range)
>int range;
>{
> if range = 0
> return(0);
> else return (rand() % range);
>}
This is not the best solution for two reasons. First, unless range
is a divisor of the maximum value returned by rand() plus one then
the numbers will not be distributed evenly over the range. Second,
even the best PRNG's are not very random in their least significant
bits, so you want values which use the most significant bits.
A simple portable solution would be to use drand48():
#define RANDOM(RANGE) ((int)(drand48()*(RANGE)))
If you don't want to use floating point numbers or need more speed
and know that longs are bigger than ints you could use (assuming
rand() returns a value between zero and MAXINT):
#define RANDOM(RANGE) ((int)(((long)rand()*(RANGE))/(MAXINT+1)))
Or else if you know range is never going to be bigger than say 256 use
something like:
#define RANDOM(RANGE) (((rand()/256)*(RANGE))/((MAXINT+1)/256))
Andrew.
--
Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712
Re: rand() within a range.
Author: logan shaw
Date: Wed, 12 Dec 1990 19:08
Date: Wed, 12 Dec 1990 19:08
17 lines
1201 bytes
1201 bytes
In article <666@sheoak.bcae.oz> 737104@sheoak.bcae.oz (David Thiele) writes: >Is there a way to generate random numbers within a certain range in >Lattice C??. ... Well, assuming you are already writing an amiga specific application and this won't hurt portability, you could use the amiga.lib function rangerand(). You pass it a longword (with a value from 1 to 65535) and it returns a random number between 0 and that number. If you are being portable, use a macro. Hope that helps... -- =----------------Logan-Shaw---(lshaw@ccwf.cc.utexas.edu)----------------= "Trust in the Lord with all thine heart, and lean not on thine own understanding. In all thy ways acknowledge Him and he shall direct thy paths" - Proverbs 3:5-6
Clicking Drives
Author: Daryl Scott Cantrell
Date: Wed, 12 Dec 1990 20:24
Date: Wed, 12 Dec 1990 20:24
19 lines
1231 bytes
1231 bytes
Could some kind soul with access to v36 includes mail/post the value of: TDPF_NOCLICK struct TDU_PublicUnit (the definition) I think both are located in either devices/trackdisk.h or stdlib.h.. Thanks in advance for any help. -- Programmer = (BypassesOpSys ? HAS_NO_TALENT : HAS_TALENT); +---------------------------------------+----------------------------+ | // Daryl S. Cantrell | These opinions are | | |\\\ milamber@caen.engin.umich.edu | shared by all of // | | |// Evolution's over. We won. | Humanity. \X/ | +---------------------------------------+----------------------------+
Re: rand() within a range.
Author: Kent Paul Dolan
Date: Thu, 13 Dec 1990 05:24
Date: Thu, 13 Dec 1990 05:24
20 lines
1309 bytes
1309 bytes
andrew@teslab.lab.oz.au (Andrew Phillips) writes:
>If you don't want to use floating point numbers or need more speed
>and know that longs are bigger than ints you could use (assuming
>rand() returns a value between zero and MAXINT):
>#define RANDOM(RANGE) ((int)(((long)rand()*(RANGE))/(MAXINT+1)))
^^^^^^^^probably not
>Or else if you know range is never going to be bigger than say 256 use
>something like:
>#define RANDOM(RANGE) (((rand()/256)*(RANGE))/((MAXINT+1)/256))
^^^^^^^^nope
Your first example will overflow to MAXNEGINT if the compiler chooses
to do the promotion to long as late as possible, and your second one
is guaranteed to overflow.
Kent, the man from xanth.
<xanthian@Zorch.SF-Bay.ORG> <xanthian@well.sf.ca.us>
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads