# More discussion on RND

March 9 2004 at 1:37 PM

Response to Use of RANDOMIZE TIMER

Why does RND always give the same numbers?

Short answer: You need to put RANDOMIZE TIMER at the beginning of your program.

If you keep doing PRINT RND, you will get a sequence of numbers that appear to be random. In fact, they are a fixed sequence of numbers and when you get to the end, it repeats. This is not a big problem, because the sequence is 16,777,216 numbers long!

Although you see numbers returned in the range 0-0.9999999..., in reality the sequence is a list of unique numbers in the range 0-16777216. The current number retained by QBasic is called the SEED. When you do Y=RND, the SEED is used to compute the next SEED which is retained. Then Y is set to that new SEED/16777216.

When you first start QBasic, the SEED is arbitrarily set to 327,680. Therefore, you always start at the same point and get the same numbers.

If you do RANDOMIZE TIMER, the SEED is set to some other value.

So a good practice is to debug your program without RANDOMIZE TIMER, so you always get the same results and can repeat test cases. Then when your program is debugged, put RANDOMIZER TIMER as the first instruction. Voila!

Mac

QBasic and VBasic result of RND
===============================

If you start a QBasic or VB program and print RND before any other randomize statement such as RANDOMIZE TIMER, you will get 0.7055475115776062 (rounded). That is 11837123/16777216. You will get this every time you run the program. In more detail, you get these results for RND*16777216:
...
12135126
7796289
327680 <Last number before sequence repeats
11837123 <First number at start of program
8949370 <Next number returned by RND
9722709 <etc.
4858052
5065847
...

The initial seed was 327680 = RND(0) * 16777216

RND(0) * 16777216 always is the current seed value.

If you insert RANDOMIZE TIMER at the beginning of your program, another number is selected as the initial seed as a function of the timer. This gives different start place (seed) in the sequence every time you run the program.

Each time you do RND, the following occurs (or something like it)
Temp# = (16598013# * Seed#) + 12820163
Seed# = (Temp# - INT(Temp# / 16777216)) * 16777216
Value-to-be-returned = Seed# / 16777216

What happens in the case of, for example "RANDOMIZE 3"?
...
7376207
914134
10001985
4196352 <Last number before sequence repeats
2328259 <First number after RANDOMIZE 3
14407290 <Next number returned by RND
12223317 <etc.
7841988
14988407
...

The initial seed was 4196352 = RND(0) * 16777216

But what happens if we first do Y=RND (which puts us at a different place in the sequence) and then do RANDOMIZE 3?
...
2378966
4034625
10039808
4196547 <Last number before sequence repeats
938106 <First number after Y = RND: RANDOMIZE 3
9114965 <Next number returned by RND
13497028 <etc.
9033335
12105566
...

The initial seed was 4196547 = RND(0) * 16777216

4196352 is not 4196547 (But close, differs by 65*3)

I did various experiments and could not determine the exact algorithm, but basically, RANDOMIZE N produces a seed that is a function of N and the current seed. Thus it is a poor way to seed for cryptography or game recovery or any application where you want to get the same results again.

RANDOMIZE 3 will always give the same result if issued as the first instruction, but whenever issued after other RND usage, it will give other results.

This is as opposed to Y = RND(-N)
...
15922689
4194496
16161923 <Last number before sequence repeats
15308090 <First number after Y = RND(-3)
16533269 <Next number returned by RND
7429508 <etc.
12228151
13989918
...

The initial seed was 16161923 = RND(0) * 16777216

But even after other RND operations, Y = RND(-3) always sets the seed to 16161923 (by whatever function of -3 is used)

Y = RND(-N) will always reset the sequence to the same place.

That is about all there is to RND, but some may insist "These are therefore not random numbers, they are pseudo-random numbers."

This is generally unimportant intellectualism run amok. Who cares? The numbers are random enough for games we write in QBasic, for screen savers, etc., etc.

Even for cryptography, the only problem is that the sequence is not long enough.

Note that if I use INT(RND*10), I will get a digit. If I use it again, I will get another digit.

There are 16777216/10 cases of the first digit.
There are 16777216/100 cases of the pair
So if I gave you a three-digit sequence, there would be 16,777 cases of what the next digit would be. In other words, it is random!

True, if I gave 8 digits, you might be able to find the place in the RND series that gives those digits, and you might find there is no other such place. In that case, the next digit is no longer random. You know what it will be.

So RND would be bad to use in a casino. If you knew how it was being used, you could theoretically compute the next number to come up on the roulette table.

But even that is not true if you use RANDOMIZE TIMER. Assume after bets are placed and the SPIN key is pressed, you issue that command. Then nobody will be able to predict what number will come up. RND will return a true and perfect random number.

More Details
============

http://www.network54.com/Hide/Forum/message?forumid=178387&messageid=1051100317

http://www.network54.com/Hide/Forum/message?forumid=178387&messageid=1012085898

 This message has been edited by iorr5t on Mar 30, 2004 9:08 AM

 Respond to this message
Responses