Random numbers
A test or a simulation wants random numbers it can repeat; a game wants different ones each time. Both come from a seed: the same seed gives the same sequence.
#import "std/numeric"
'' randomize with a seed makes rnd repeat the same sequence.
randomize 42
print "rnd:";
for i as int32 = 1 to 3
print rnd( );
next
print
'' numeric.Rng is a generator you hold: each one is its own stream.
dim dice as numeric.Rng = numeric.RngSeeded( 2025 )
print "ten dice:";
for i as int32 = 1 to 10
print dice.NextInt( 1, 6 ); '' both ends included
next
print
'' The same seed gives the same stream, on every platform.
dim again as numeric.Rng = numeric.RngSeeded( 2025 )
print "same seed:";
for i as int32 = 1 to 10
print again.NextInt( 1, 6 );
next
print
'' Shuffle an array; every order is equally likely.
dim cards( 1 to 6 ) as int32 = { 1, 2, 3, 4, 5, 6 }
numeric.Shuffle( dice, cards( ) )
print "shuffled:";
for i as int32 = 1 to 6
print cards( i );
next
print
'' A double from 0 up to, but not including, 1.
var x = dice.NextDouble( )
print "0 <= x < 1: "; cbool( x >= 0 andalso x < 1 )
Output
rnd: 0.8665110266301781 0.1258447782602161 0.3785038157366216
ten dice: 5 3 3 4 6 2 4 3 6 4
same seed: 5 3 3 4 6 2 4 3 6 4
shuffled: 6 2 5 4 3 1
0 <= x < 1: true
The built-in pair is randomize, which seeds the program's one generator, and
rnd( ), which returns a value from 0 up to but not including 1. With a fixed
seed, as here, every run prints the same numbers.
numeric.Rng is a generator you hold. An Rng is a value: each one is its
own stream, so one part of a program can have a repeatable stream without
disturbing another's, and a copy carries on from the same point.
RngSeeded( seed ) gives the same numbers on every platform, which is what
tests need; RngFromEntropy( ) seeds from the operating system for a different
stream on each run.
| Member | Gives |
|---|---|
NextInt( lo, hi ) | a whole number from lo to hi, both included, with no bias |
NextDouble( ) | a float64 from 0 up to but not including 1 |
NextBoolean( ), NextBooleanP( p ) | true half the time, or with probability p |
NextNormal( ), NextNormalP( mean, sd ) | values on a bell curve |
numeric.Shuffle( rng, a( ) ) puts an array in random order, every order
equally likely, and numeric.Choice( rng, a( ) ) picks one element. For keys
and tokens, where nobody may predict the value, use numeric.CryptoBytes or
numeric.CryptoULongInt; they have no seed.
int( rnd( ) * 6 ) + 1 is the classic die roll. It is very slightly biased;
NextInt( 1, 6 ) is not.
Activities
- Roll two dice 1000 times with a seeded
Rngand count how often they sum to 7. - Seed with
RngFromEntropy( )and run the program twice.