A ''subtractive generator'' calculates a sequence of [[random number generator|random numbers]], where each number is congruent to the subtraction of two previous numbers from the sequence.
The formula is
*
for some fixed values of , and , all positive integers. Supposing that , then the state of this generator is the list of the previous numbers from to . Many states generate uniform random integers from to , but some states are bad. A state, filled with zeros, generates only zeros. If is even, then a state, filled with even numbers, generates only even numbers. More generally, if is a factor of , then a state, filled with multiples of , generates only multiples of .
All subtractive generators have some weaknesses. The formula correlates , and ; these three numbers are not independent, as true random numbers would be. Anyone who observes consecutive numbers can predict the next numbers, so the generator is not cryptographically secure. The authors of ''Freeciv'' ([http://svn.gna.org/viewcvs/freeciv/trunk/utility/rand.c?view=markup utility/rand.c]) and ''xpat2'' (src/testit2.c) knew another problem: the low bits are less random than the high bits.
The subtractive generator has a better reputation than the [[linear congruential generator]], perhaps because it holds more state. A subtractive generator might never multiply numbers: this helps where multiplication is slow. A subtractive generator might also avoid division: the value of is always between and , so a program only needs to add to negative numbers.
The choice of and affects the period of the generator. A popular choice is and , so the formula is
*
The subtractive generator from ''xpat2'' uses
*
The implementation is by J. Bentley and comes from program_tools/universal.c of [ftp://dimacs.rutgers.edu/pub/netflow/ the DIMACS (netflow) archive] at Rutgers University. It credits Knuth, [[wp:The Art of Computer Programming|''TAOCP'']], Volume 2, Section 3.2.2 (Algorithm A).
Bentley uses this clever algorithm to seed the generator.
# Start with a single in range to .
# Set and . The inclusion of avoids some bad states (like all zeros, or all multiples of 10).
# Compute using the subtractive formula .
# Reorder these 55 values so , , , ..., .
#* This is the same order as , , , ..., .
#* This rearrangement exploits how 34 and 55 are relatively prime.
# Compute the next 165 values to . Store the last 55 values.
This generator yields the sequence , , and so on. For example, if the seed is 292929, then the sequence begins with , , . By starting at , this generator avoids a bias from the first numbers of the sequence. This generator must store the last 55 numbers of the sequence, so to compute the next . Any array or list would work; a [[ring buffer]] is ideal but not necessary.
Implement a subtractive generator that replicates the sequences from ''xpat2''.