I knew that calling *RND(1)* uses the previous result as the seed for the
random number generator and that one can instead seed it manually by
calling *RND(-X)*, but I had thought it was similar to Microsoft BASIC-80
(MBASIC) which limited the seed to the range -32,768 to 32,767. Boy, was I
wrong!

It appears, any 15 digit number can be used as a seed. That is impressive
since the number of different unique simulations (games) that can be played
depend upon how many seeds are possible. For BASIC-80, there were only
65,536, while the Model T boasts 10^16 — 10,000,000,000,000,000 — different
random number sequences.

But, to use that power, the programmer has to know that it's available and
seed it properly, which certainly hasn't always been the case. I cannot
find it documented anywhere clearly. For example, the venerable Programming
Tips, Peeks, and Pokes
<https://archive.org/details/ProgrammingTipsPeeksAndPokesForTheTandyPortableComputers/>
by Anderson includes a tip which uses only 125 different seeds:

IF PEEK(1) = 171 POKE 63277, PEEK(61983) ELSE POKE 64634, PEEK(63791)

Anderson's testing actually revealed
<https://archive.org/details/ProgrammingTipsPeeksAndPokesForTheTandyPortableComputers/page/n31/mode/1up>
that the random number generator's cycle (length before repeating from a
single seed) is extraordinarily long. Here's what he had to say:

Copyright 1987 Tony B. Anderson All Rights Reserved
>
> The random number generator in the Model 100 seems to be better than most
> folks have been led to believe, me included. Some comments by others that
> it would "recylce" itself, and start repeating the same series of random
> numbers after about 64,000 numbers, got me curious... So I set up the
> following short program to see whether that was true.
>
> 10 CLS : PRINT "Random Generator Test"
> 20 PRINT"Start Time: "TIME$
> 30 A=RND(1) : PRINT"First Number ="A
>
40 C=1 :PRINT"Count ="
> 50 B=RND(1) : C=C+1 : PRINT@128, C
>
60 IF B=A THEN PRINT:PRINT"Match at "TIME$
> 70 GOT050
>
> Well, the program ran for 41 hours, generating about 22 numbers per
> second, racking up a total of 3,259,022 random numbers, without ever
> matching the first number! I only stopped the program since I needed the
> computer for other purposes, and couldn't allow it to continue.
>
> Interestingly, the random number generator returns a fourteen-digit number
> between .00000000000001 and .99999999999999.
>
> But on the basis of that test, I'd say the random number generator is
> capable of much more than we previously thought. It may be that some
> particular combination of "adjusting" the generator output to get integers
> or "real" numbers within a certain range, might show a repeating series
> after a certain number of operations, but it was not possible for me to
> test this theory, since it would depend on a specific-case instance, and
> only be duplicatable by the exact same code.
>

Surprisingly, Anderson later writes as if there is only one memory address
(a single byte) that holds the "seed" number, which clearly can't be the
case as it would have cycled after 256 calls to RND(1). Looking at the
memory addresses adjacent to the one he identified, it seems to me that
there are seven bytes being used for the seed as they get updated every
time I call *rnd(X)*. They appear to be precisely the bytes of a floating
point number, if one skips the first byte (the base 10 exponent).

10 IF PEEK(1) = 171 THEN S=63277 ELSE S=64634
20 X=RND(0):  REM Last result & current seed
30 PX=VARPTR(X):  REM Address of X
40 FOR I=0 TO 6: ?PEEK(S+I);: NEXT: ?
50 FOR I=1 TO 7: ?PEEK(PX+I);: NEXT: ?
60 X=RND(1)
70 GOTO 40

Seven bytes (56 bits) for a seed is a *lot*: over 10¹⁶
(10,000,000,000,000,000) numbers!

Clearly, this is overkill for most Model T apps, but I think it's nifty
that Bill Gates thought it might be useful. I have some questions though:

   - Is my analysis correct and, if so, why was such a robust algorithm
   used?

   - Does anyone know if there are any programs that actually use the
   ability to seed to the full extent?

   The sources of entropy seem limited on a Model T. One could use the two
   memory locations that count to 125 and 12, but that's only 10.55 bits
   [log₂(125) + log₂(12)]. Adding a splash screen and measuring the time
   before the user hits a key, could double that to 21 bits, but only if we
   pretend that some users might wait as long as 12 seconds, which seems
   unlikely. Adding in date and time increases the total to 52 bits, though
   with low quality entropy. That's all the sources of randomness I know of
   and it's still not 56 bits.

   - Are all the seeds actually usable or are there certain seed numbers
   which lead to short cycles where the random numbers repeat too soon (after
   maybe a measly billion calls to RND)?

—b9

*Caveats*: Using the BASIC interface to the seed limits which numbers can
be used in two ways. First, only fifteen digits are significant. Second,
the base 10 exponent is ignored, thus RND(-1), RND(-1000), and
RND(-0.00001) are all equivalent.

Reply via email to