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.