Thanx in advance.
Glen Balmer @wyvern.cs.uow.edu.au
8-)
You've got a very good one in your SAS/C libraries, if used correctly.
It is called "rand()".
There's not enough space to go into the theory here (though there are
several good books on the subject), but suffice it to say that rand()
uses what's called the "Linear Congruential Algorithm" to calculate the
next random number from the previous.
A peculiarity of this algorithm is that the upper bits of the number
will be "more random" than the lower bits ((Fuzzy Logic, anyone?)), but
most people have tried to use the lower bits and complained that the
numbers aren't very good.
Most commonly, you see something like:
x = rand() % 20;
to try to get a random number less than 20. People have found out that
this tends to give them a very nice cycle of EVEN ODD EVEN ODD EVEN ODD
etc., etc.
To more properly use this function, you need to access the upper bits of
the value returned by rand(), such as:
x = (rand() >> 16) % 20;
where increasing or decreasing the '16' in the line above will vary the
"randomness" of the value stored in 'x'.
Truthfully, we need to either clarify this in our docs, or change
algorithms so people will not run into these problems...
--
---------------
Jim Cooper
(ja...@unx.sas.com) bix: jcooper
Any opinions expressed herein are mine (Mine, all mine! Ha, ha, ha!),
and not necessarily those of my employer.
It appears that SAS/C's rand() follows the path of the traditional UNIX
rand() function. I use GCC on my Amiga, and it's docs explicitly state
that rand() is a "bad random number generator". It suggests that you
use the random() function instead, and mentions that rand() conforms to
ANSI C.
GCC's random() function, which uses a "non-linear additive feedback random
number generator", maintains an internal table of 31 long integers
for it's RNG generation. The manual states that all 32 bits of output
are random (as opposed to rand(), where the low dozen bits go through a
cyclic pattern, and that random() has a cycle of approximately
16*(2^31-1) (which is nearly 16 times longer than rand() could possibly
be, given only 31 bits of internal state).
There is also a rand48() family, which uses an even different algorithm
(gcc doesn't provide rand48()), that also was originally developed as a
replacement for rand().
>
>Truthfully, we need to either clarify this in our docs, or change
>algorithms so people will not run into these problems...
>
Perhaps SAS might want to look into providing something like random()?
I believe that GCC is using the library source from the NET2 Berkeley
Unix release, which would have the restrictions of UC Berkeley, not FSF.
In any event, the man pages I'm reading are Berkely Experimental man
pages, so I'm sure that Berkeley has a random() function written in
freely available code.
>--
>---------------
>Jim Cooper
>(ja...@unx.sas.com) bix: jcooper
>
>Any opinions expressed herein are mine (Mine, all mine! Ha, ha, ha!),
>and not necessarily those of my employer.
--
-----
Buddha Buck bmb...@ultb.isc.rit.edu
(insert-file ".disclaimer")
"I'm not an actor, but I play one on TV."
Bye 8-) 8-)
Glen Balmer...
|> Perhaps SAS might want to look into providing something like random()?
We do provide rand48() family of functions.
--
***** / wal...@unx.sas.com
*|_o_o|\\ Doug Walker< BIX, Portal: djwalker
*|. o.| || \ CompuServe: 71165,2274
| o |//
======
Any opinions expressed are mine, not those of SAS Institute, Inc.
If memory serves (it will have to as my autodocs are at home and I am not),
one of the shared libraries implements a random number generator using
(again, according to the autodocs) a "Linear Cong...."
If this is so, then it might be worth while to look into it as it is
sure to be smaller than linking in something from the SAS library.
All this assumes that memory serves and that the routine actually
works as advertised.
Grins,
+------------------------------+------------------------------+
| Scott R. Quier | s.r....@larc.nasa.gov |
+------------------------------+------------------------------+
| I would rather burn out than rust out |
|All opinions are my own, reflect poorly on myself and not at |
|all on any other creature or concern. |
+-------------------------------------------------------------+
>A peculiarity of this algorithm is that the upper bits of the number
>will be "more random" than the lower bits ((Fuzzy Logic, anyone?)), but
>most people have tried to use the lower bits and complained that the
>numbers aren't very good.
Another routine is lrand48() and it's friends. I advise _against_
using it. It's VERY VERY susceptible to problems like that. For example,
lrand48()%N always being odd or even, etc (for a given N).
--
GNU Emacs is a LISP operating system disguised as a word processor.
- Doug Mohney, in comp.arch
Randell Jesup, Jack-of-quite-a-few-trades, Commodore Engineering.
je...@cbmvax.commodore.com or rutgers!cbmvax!jesup BIX: rjesup
Disclaimer: Nothing I say is anything other than my personal opinion.
If these are not good enough for your applications you can also
code your own using logic, ie simulate the asynchronous logic often used
to generate PR sequences, they are not really that complex, and should
not really cause any significant processing loss.
A great trick to 'increase' randomness, is to make the random
sequence dependant on user input (ie the time between user inputs, in
microseconds (always pretty random)), this time period can also be used
as a random seed for the rand() funcion, and if you continually reseed
it with these kind of random numbers, it is highly unlikely there will
be a pattern easily recognisable.
mike
--
----------------------------------------------------------------------
NO! I'm not a square,,,,, I'm a cube!
-----------------------------------------------------------------------
JOKE == (:->) Michael Nielsen @ 1993