Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

MemberGives
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

  1. Roll two dice 1000 times with a seeded Rng and count how often they sum to 7.
  2. Seed with RngFromEntropy( ) and run the program twice.