| Home CBM ASCII-X BASIC Disk Commands Enter RUN mode Program Format Secret Variables Variable Format Expressions Keywords (divide) (equal) (less) (minus) (more) (multiply) (plus) (power) Abs And Append Asc Atn Auto Backup Bank Begin Bend Bload Boot Box Bsave Bump Catalog Char Chr Circle Close Clr Cmd Collect Collision Color Concat Cont Copy Cos Data Dclear Dclose Dec Def Delete Dim Directory Dispose Dload Do Dopen Draw Ds Ds string Dsave Dverify El Else End Envelope Er Err Exit Exp Fast Fetch Filter Fn For Fre Get Get num Getkey Go Gosub Goto Graphic Gshape Header Help Hex If Input Input num Instr Int Joy Key Left Len Let List Load Locate Log Loop Mid Monitor Movspr New Next Not Off On Open Or Paint Peek Pen Pi Play Pointer Poke Pos Pot Print num Pudef Quit Rclr Rdot Read Record Rem Rename Renumber Restore Resume Return Rgr Right Rlum Rnd Rreg Rspcolor Rsppos Rsprite Run Rwindow Save Scale Scnclr Scratch Sgn Sin Sleep Slow Sound Spc Sprcolor Sprdef Sprite Sprsav Sqr Sshape St Stash Step Stop Str Swap Sys Tab Tan Tempo Then Ti Ti string To Trap Troff Tron Until Using Usr Val Verify Vol Wait While Width Window Xor Syntax Tokens C128 D64plus Disk Escape Codes Hardware PCxface PETSCII Pet2asc Futurama IBM PC-AT Contact Games Glossary Hall of fame Hall of shame Miscellaneous Privacy policy Programming Twisty puzzles |
RND ( value )
Calculate a psudo-random number.
The RND function is primarily used to generate a psudo-random number. Psudo-random means the value is difficult predict, but not truly random. CBM BASIC provides two ways to get a "random" number. One way is to supply a value of zero to RND; in this case RND will generate a "random" number based on hardware timers and also update a Secret Variable called the seed. The second way is to supply any positive value to RND; in this case it will generate a "random" number based on the current seed (and update the seed in the process). I prefer to combine the methods: use a zero value at the start of the program to set a "random" seed based on the hardware timers and then use a positive value in the main loop of the program to generate a "random sequence". I do this to avoid potential skewing of the results based on the periodic nature of the hardware timers. Another, rarely used option, is to pass a negative value to RND which will set a specific seed. This may be useful for testing as it will result in the same sequence of "random" numbers if you only use RND(1) in the future (i.e., in any positive value). The result will be a floating-point number from zero up to, but not including, one. To get an an integer number between min and max (inclusive), use the forumla: R = min + INT( (max - min +1) * RND(1) ) For example, to get a random number from 1 to 6 to simulate the roll of a die, the forumula would work out as R = 1 + INT(6*RND(1)). There has been some controversy around the RND function. Mainly this involves the "quality" (or lack thereof) of the random values generated. From my research, the poor quality seems to be a more serious issue in other (non-CBM) versions of BASIC. This is probably due to a combination of poor algorithm along with limited precision (CBM features 32-bit floats, while most other 8-bits use only 24-bit floats). In CBM BASIC, it seems many programs are using a 0 value which may reduce quality based on the peiodic nature of the hardware timers (as explained above). There are several statical measures that can be applied to a sequence of numbers, and which ones are important tends to vary upon the intended use of the random numbers; hence another reason for debate. My limited experiments (using my preferred/combined method) show that usually all values in 1-d or 2-d sense will eventually occur, and most of them with roughly the same frequency. In a 3-d and 4-d sense the "random" numbers often will hit all possible combinations, but in a few cases (an "unlucky seed") some combinations never occur. I think this could be avoided (but haven't verified) if you call RND(0) to re-seed the sequence on rare occassions (like maybe 1 in 5000, or even less often). Another thing to consider is that the quality of the results may depend on how often / when you call RND. If you call it routinely in a programmed loop (for example to draw a field of "stars" on a bitmap) the RND function will get called at a fairly predictible rate so that RND(0), which bases its results on the hardware timers, may be heavily skewed. On the other hand, if you only occassionaly or "randomly" call RND(0) (for example, when the user performs a certain task) it may give "better" results than RND(1); the reason being that the user (if human) will generally not do things on a very precise time schedule (thus the hardware timers will tend to be "randomly out of sync" relative to the last time they were checked). Anyway, I think using RND(0) to initialize the seed and RND(1) in loops is a good strategy. If you don't trust BASIC (or my experimental results), some CBM machines have a SID chip which can be programmed to generate "random" numbers too; I haven't compared the quality of the two methods, but POKEing and PEEKing seems like it would be slower than using RND. BASIC sets the seed to a constant value stored in ROM on power-up. Thus, if you use RND(1) without initializing the seed your program will generate the same set of "random" numbers if you run it after power-up. The BASIC versions are not consistant about the initial value returned by RND(1) or how they update the seed when given a negative value. Thus on a single machine, you can set a specific seed (with either a negative value or the power-up method) and get a reliable sequence of numbers; but running the same program on a different machine may give different results... compare and contrast the examples. If the value is omitted or not a valid expression, SYNTAX ERROR is generated. If the value is not numeric, a TYPE MISMATCH ERROR occurs. I almost forgot! Some other BASICs use the value supplied to RND to determine the range of the result. As explained above, CBM BASIC always returns a result in the range of 0 to 1 (the value is only used to specify a method used to generate the result or possibly set an initial seed). Examples (Plus/4 or C128):
Examples (C64):
© H2Obsession, 2014 |