Skip to content

Instantly share code, notes, and snippets.

@tommyettinger
Created July 9, 2017 05:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tommyettinger/e55763edf88e6927e9a5eb254f05853d to your computer and use it in GitHub Desktop.
Save tommyettinger/e55763edf88e6927e9a5eb254f05853d to your computer and use it in GitHub Desktop.
Tiny Java utilities for generating high-quality random int values from a large state array
public class RandomUtils
{
/**
* Generates a state array for use with {@link #randomInt(int[])}; this state array will be random using {@code Math.random()}.
* @return a 129-element int array with contents randomized by {@code Math.random()}
*/
public static int[] initialState()
{
final int[] state = new int[129];
for(int i = 0; i < 129; i++)
{
state[i] = (int)((Math.random() * 2.0 - 1.0) * 0x80000000);
}
return state;
}
/**
* Generates a state array for use with {@link #randomInt(int[])}; this state array will be determined by the given {@code seed}.
* @param seed can be any int; will determine the contents of the returned state, but only 2 to the 32 states will be possible
* @return a 129-element int array with contents determined by seed
*/
public static int[] initialState(int seed)
{
final int[] state = new int[129];
for(int i = 0, z; i < 129; i++)
{
z = (seed += 0x9E3779B9);
z = (z ^ (z >>> 16)) * 0x85EBCA6B;
z = (z ^ (z >>> 13)) * 0xC2B2AE35;
state[i] = z ^ (z >>> 16);
}
return state;
}
/**
* Gets a random number given a large array of state. This should be called with an int array for state that has a
* length of at least 129, and the array will be altered by this call. There are no restrictions on what the
* contents of state can be; it can be all 0 on the first call. For the quality to stay intact, it is recommended
* that {@code state[128]} not be changed except by this method; that element is normally the last one in the
* recommended size of array, and it is used to store special state that should change in a specific pattern.
* When used as intended, this should pass stringent tests for random number quality.
* @param state int array that must have a length of at least 129; contents will be changed
* @return a pseudo-random int using the given state and choice
*/
public static int randomInt(int[] state)
{
final int c = (state[128] += 0xB9A2842F);
return (state[c * 0x85157AF5 >>> 25] += (c >>> (c >>> 28)) * 0x632BE5AB);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment