🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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.
#7186
Author: David Thiele
Date: Mon, 03 Dec 1990 23:20
21 lines
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.
#7204
Author: Dolf Grunbauer
Date: Wed, 05 Dec 1990 07:43
47 lines
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.
#7235
Author: Henrik Clausen
Date: Wed, 05 Dec 1990 16:31
27 lines
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.
#7252
Author: Aaron Friesen
Date: Wed, 05 Dec 1990 23:50
13 lines
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.
#7226
Author: Kent Paul Dolan
Date: Thu, 06 Dec 1990 03:31
88 lines
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.
#7266
Author: Narciso Jaramillo
Date: Thu, 06 Dec 1990 17:26
38 lines
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.
#7273
Author: Dan Barrett
Date: Fri, 07 Dec 1990 21:41
47 lines
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.
#7405
Author: Andrew Phillips
Date: Tue, 11 Dec 1990 06:15
38 lines
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.
#7417
Author: logan shaw
Date: Wed, 12 Dec 1990 19:08
17 lines
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
#7438
Author: Daryl Scott Cantrell
Date: Wed, 12 Dec 1990 20:24
19 lines
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.
#7436
Author: Kent Paul Dolan
Date: Thu, 13 Dec 1990 05:24
20 lines
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