Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to properly generate a random integer.

135 views
Skip to first unread message

Nick

unread,
Jan 9, 2007, 1:05:17 AM1/9/07
to
My HP 50G's rand function is rather limiting when I need a random
integer. I tried to write a simple program to generate a random integer
from a random number between 0 and 1:
<< RAND 10. 12 ^ * 10. MOD >>

The thought that was since there was 12 significant digits of
precision, multiplying by 10 to the 12fth would get me an integer that
I could the use the MOD function on. The problem is when the number is
between, 0 and .1, the silly floating point numbers still have 12
significant digits, so about 10% of my random integer end up not being
integers at all... What is the proper way to do this?

VJP

unread,
Jan 9, 2007, 2:17:06 AM1/9/07
to

Use IP to force integer result. Eg << RAND 10. 12 ^ * IP 10 MOD >>.
Also, The constant 1.E12 is equivalent to 10. 12 ^ *

However, I don't know how random the result will be by picking the nth
decimal place - I suppose it depends on how important randomness it is
to your application. A simpler routine such as << RAND 10 * IP >> may
be just as valid.

VJP

John H Meyers

unread,
Jan 9, 2007, 5:41:14 AM1/9/07
to
On Tue, 09 Jan 2007 00:05:17 -0600, Nick wrote:

> My HP 50G's rand function is rather limiting
> when I need a random integer.

> What is the proper way to do this?

"Random integer" is a fuzzy concept;
if you want to select a random integer
*uniformly*distributed* in the *range* of 1 to 6, say
(to simulate throwing a die), then RAND 6 * CEIL
is the way to go -- it's known that HP's RAND can never result
in an output of either exactly zero or exactly 1,
and that the above can therefore *never*
give any result less than 1 nor more than 6.

If we want a result in a range such as 0 thru 4,
however, would RAND 5 * IP suffice?

Well, what happens if RAND returns .999999999999 ?
Then .999999999999 5 * IP produces 5 (surprise!),
whereas RAND 5 * CEIL 1 - can not possibly
deliver any unintended result, ever.

Thus it's safest to always use CEIL after RAND N *,
and then adjust for any different desired result range.

Note that multiplying RAND output by *large* integers
(especially powers of 10) starts to go awry,
because this in effect discards some of the leftmost digits,
and it so happens that HP's RAND is ever more "regular"
in the patterns of its rightward digits;
therefore, if you need to throw "random" 1E10-sided dice,
it would be much better to instead generate one random digit
at a time, via RAND 10 * CEIL, repeating this ten times,
and to *never* use MOD with the output of RAND.

Although other calculators employ much fancier algorithms
to generate results that don't have such patterns,
it is perfectly possible, with care, to employ HP's RAND properly
to produce end results without artifacts,
although "fancier" RAND algorithms are much more resistant
to the effects of improper use through casual
but inappropriate programming.

"Generating random numbers is too important to be left to chance" :)
(Knuth vol 2 chapter 3 contains a mere 175 pages devoted to this subject)

[r->] [OFF]

hga...@xmission.com

unread,
Jan 9, 2007, 6:38:57 PM1/9/07
to
When is a linear, congruential, pseudo random number generator "good
enough"? One criterion is whether or not the generator passes the
spectral test (described in the reference John mentions: Knuth, The
Art of Computer Programming, Seminumerical Algorithms).

And here is a link to the spectral test server of the Uni Salzburg:

http://random.mat.sbg.ac.at/results/karl/spectraltest/index.html

Enjoy!

Nick

unread,
Jan 9, 2007, 7:50:25 PM1/9/07
to

Thanks! The CEIL method is working great!

Arnaud Amiel

unread,
Jan 14, 2007, 1:50:53 PM1/14/07
to
Just out of interest, to try to see how to do it, I had started a
slightly related blog there:
http://aamiel.blogspot.com/

However, it was just to check the Blogger service so not very useful.
You can still have a look.

Arnaud

mark4...@aol.com

unread,
Feb 10, 2007, 12:59:41 PM2/10/07
to
On Jan 9, 6:38 pm, "hgab...@xmission.com" <hgab...@xmission.com>
wrote:

> When is a linear, congruential, pseudo random number generator "good
> enough"? One criterion is whether or not the generator passes the
> spectral test (described in the reference John mentions: Knuth, The
> Art of Computer Programming, Seminumerical Algorithms).

These generators have been surpassed in the last decade by a new
algorithm:

http://en.wikipedia.org/wiki/Mersenne_twister

Many commercial statistics programs (e.g. SAS, JMP) use it. The main
advantage is the much, much longer period. Today that advantage is
very real. Simulations and Monte Carlo methods like pernutation tests
and bootstrapping exhaust the older linear congruential generators
when working on real problems and real data sets, something I never
thought would happen twenty-five years ago!

That advantage may not be important at all for applications on a hand-
held calculator. Just posting it for your information.

John H Meyers

unread,
Feb 10, 2007, 8:24:12 PM2/10/07
to
On Sat, 10 Feb 2007 11:59:41 -0600:

> http://en.wikipedia.org/wiki/Mersenne_twister

Based on binary operations and outputs
a 32-bit or 64-bit *binary* value,
according to this article (are there decimal versions?)

32 bits binary is roughly equiv. to 9 decimal digits,
not enough for 15-digit mantissa (or even 12),
regardless of huge period (length of period
is thus not quite as overwhelmingly significant as it sounds,
just like other lengths pitched in everyday spams :)

Suggest what to do on BCD (decimal) calculator?

Period of highly unsophisticated HP MRNG
is 5E13, I think; if you have a handheld calculator
which can generate one output per microsecond,
it will take about a year and a half to complete a cycle.

The worst thing about the built-in RAND is that
it is very easy to use it improperly,
and it's poor for generating large random integers
(which can be improved by some programming;
of course you could just program a complete new RAND instead);
also a very poor and limited RDZ (initialization),
needing a program with manual user help
to acquire a decent amount of unpredictable initial state.

Knowing *one* 15-digit RAND value is also sufficient
to predict all future values.

However, RAND should be adequate for most games,
which may be its principal use in calculators :)

[r->] [OFF]

Albert Graef

unread,
Feb 11, 2007, 7:10:43 AM2/11/07
to
John H Meyers wrote:
> Based on binary operations and outputs
> a 32-bit or 64-bit *binary* value,
> according to this article (are there decimal versions?)

You mean decimal floating point numbers? Not that I know. It just
generates unsigned 32 bit integers. BTW, you also have to be careful
with the seed value (IIRC the least significant bit of the initial seed
should always be 1). Other than that, I don't think that there are any
gotchas, this algorithm really seems to work very well (I've been using
it in my Q language for many years) and it shouldn't be too difficult to
port it to RPL.

--
Dr. Albert Gr"af
Dept. of Music-Informatics, University of Mainz, Germany
Email: Dr.G...@t-online.de, a...@muwiinfa.geschichte.uni-mainz.de
WWW: http://www.musikinformatik.uni-mainz.de/ag

John H Meyers

unread,
Feb 11, 2007, 8:41:23 AM2/11/07
to
On Sun, 11 Feb 2007 06:10:43 -0600, Albert Graef wrote:

> [Mersenne Twister] just generates unsigned 32 bit integers.

One would need the 64-bit version just to map that
to 12- or 15- digit decimal floating,
and of course there's extra time needed for mapping
(and some artifacts in even trying to map it?)

> BTW, you also have to be careful with the seed value
> (IIRC the least significant bit of the initial seed should always be 1).

HP's long-used decimal MRNG also requires decimal, 15-digit seed
ending in 1, 3, 7, or 9; if seed is overlaid in memory,
the output in the very worst case can be a constant (exactly 0.5);
no check is ever made to verify or force it to conform,
except during initializing via RDZ.

[r->] [OFF]

0 new messages