Class LightRNG
java.lang.Object
java.util.Random
com.github.tommyettinger.random.EnhancedRandom
com.github.yellowstonegames.old.v300.LegacyRandom
com.github.yellowstonegames.old.v300.LightRNG
- All Implemented Interfaces:
StatefulRandomness, Externalizable, Serializable, RandomGenerator
This is a SplittableRandom-style generator, meant to have a tiny state
that permits storing many different generators with low overhead.
It should be rather fast, though no guarantees can be made on all hardware.
It should be faster than using SplittableRandom from Java 8 because it has a
single "gamma" value that prevents it from being split but also makes runtime
a bit quicker. It is based on using a unary hash on a large-increment counter,
which makes even the first item obtained from similarly-seeded LightRNGs very
likely to be very different. This is an advantage over non-hash-based RNGs.
This generator is especially fast on OpenJ9, version 0.17.0 or later (from late 2019), and can be several times faster there than on HotSpot.
Written in 2015 by Sebastiano Vigna (vigna@acm.org)
This generator is especially fast on OpenJ9, version 0.17.0 or later (from late 2019), and can be several times faster there than on HotSpot.
Written in 2015 by Sebastiano Vigna (vigna@acm.org)
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface RandomGenerator
RandomGenerator.ArbitrarilyJumpableGenerator, RandomGenerator.JumpableGenerator, RandomGenerator.LeapableGenerator, RandomGenerator.SplittableGenerator, RandomGenerator.StreamableGenerator -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptioncopy()Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called.static longdetermine(int a, int b) static longdetermine(long state) static intdetermineBounded(long state, int bound) static doubledetermineDouble(long state) Returns a random double that is deterministic based on state; if state is the same on two calls to this, this will return the same float.static floatdetermineFloat(long state) Returns a random float that is deterministic based on state; if state is the same on two calls to this, this will return the same float.booleanlonggetSelectedState(int selection) longgetState()Gets the current state of this generator.intgetTag()inthashCode()intnext(int bits) Gets a pseudo-random int with at most the specified count of bits; for example, if bits is 3 this can return any int between 0 and 2 to the 3 (that is, 8), exclusive on the upper end.booleanGets a random value, true or false.voidnextBytes(byte[] bytes) Given a byte array as a parameter, this will fill the array with random bytes (modifying it in-place).doubleGets a uniform random double in the range [0.0,1.0)doublenextDouble(double outer) Gets a uniform random double in the range [0.0,outer) given a positive parameter outer.floatGets a uniform random float in the range [0.0,1.0)intnextInt()Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.intnextInt(int bound) Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), or 0 if the bound is 0.intnextInt(int lower, int upper) Inclusive lower, exclusive upper.longnextLong()Can return any long, positive or negative, of any size permissible in a 64-bit signed integer.longnextLong(long bound) Exclusive on the outer bound; the inner bound is 0.longnextLong(long inner, long outer) Inclusive inner, exclusive outer; both inner and outer can be positive or negative.voidsetSeed(long seed) Sets the seed of this generator (which is also the current state).voidsetSelectedState(int selection, long value) voidsetState(long seed) Sets the seed (also the current state) of this generator.longskip(long advance) Advances or rolls back the LightRNG's state without actually generating each number.toString()Methods inherited from class LegacyRandom
nextSignedInt, nextSignedLongMethods inherited from class com.github.tommyettinger.random.EnhancedRandom
appendSerialized, appendSerialized, areEqual, fixGamma, fixGamma, getMinimumPeriod, lcm, mainlyGeneratesInt, maxDoubleOf, maxFloatOf, maxIntOf, maxLongOf, minDoubleOf, minFloatOf, minIntOf, minLongOf, nextBoolean, nextDouble, nextExclusiveDouble, nextExclusiveDouble, nextExclusiveDouble, nextExclusiveDoubleEquidistant, nextExclusiveFloat, nextExclusiveFloat, nextExclusiveFloat, nextExclusiveFloatEquidistant, nextExclusiveSignedDouble, nextExclusiveSignedFloat, nextExponential, nextFloat, nextFloat, nextGaussian, nextGaussian, nextGaussianFloat, nextGaussianFloat, nextInclusiveDouble, nextInclusiveDouble, nextInclusiveDouble, nextInclusiveFloat, nextInclusiveFloat, nextInclusiveFloat, nextSign, nextSignedInt, nextSignedLong, nextTriangular, nextTriangular, nextTriangular, nextTriangular, nextUnsignedInt, previousInt, previousLong, probit, processSignedInt32, processUnsignedInt32, randomElement, randomElement, rateGamma, readExternal, seedFromMath, setState, setState, setState, setState, setState, setState, setState, setState, setState, setState, setWith, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, shuffle, stringDeserialize, stringDeserialize, stringSerialize, stringSerialize, writeExternalMethods inherited from class Random
doubles, doubles, doubles, doubles, from, ints, ints, ints, ints, longs, longs, longs, longsMethods inherited from interface RandomGenerator
equiDoubles, isDeprecated
-
Field Details
-
state
public long state
-
-
Constructor Details
-
LightRNG
public LightRNG()Creates a new generator seeded using Math.random. -
LightRNG
public LightRNG(long seed)
-
-
Method Details
-
getTag
- Specified by:
getTagin classcom.github.tommyettinger.random.EnhancedRandom
-
next
public int next(int bits) Gets a pseudo-random int with at most the specified count of bits; for example, if bits is 3 this can return any int between 0 and 2 to the 3 (that is, 8), exclusive on the upper end. That would mean 7 could be returned, but no higher ints, and 0 could be returned, but no lower ints.- Overrides:
nextin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
bits- the number of bits to be returned; if 0 or less, or if 32 or greater, can return any 32-bit int- Returns:
- a pseudo-random int that uses at most the specified amount of bits
-
nextLong
public long nextLong()Can return any long, positive or negative, of any size permissible in a 64-bit signed integer.- Specified by:
nextLongin interfaceRandomGenerator- Specified by:
nextLongin classcom.github.tommyettinger.random.EnhancedRandom- Returns:
- any long, all 64 bits are random
-
copy
Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called. This just needs to copy the state so it isn't shared, usually, and produce a new value with the same exact state.- Specified by:
copyin classcom.github.tommyettinger.random.EnhancedRandom- Returns:
- a copy of this RandomnessSource
-
nextInt
public int nextInt()Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.- Specified by:
nextIntin interfaceRandomGenerator- Overrides:
nextIntin classcom.github.tommyettinger.random.EnhancedRandom- Returns:
- any int, all 32 bits are random
-
nextInt
public int nextInt(int bound) Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), or 0 if the bound is 0. The bound can be negative, which will produce 0 or a negative result. Uses an aggressively optimized technique that has some bias, but mostly for values of bound over 1 billion. This method will always advance state exactly once (equivalent to one call tonextLong()).
Credit goes to Daniel Lemire.- Specified by:
nextIntin interfaceRandomGenerator- Overrides:
nextIntin classLegacyRandom- Parameters:
bound- the outer bound (exclusive), can be negative or positive- Returns:
- the found number
-
nextInt
public int nextInt(int lower, int upper) Inclusive lower, exclusive upper. Although you should usually use a higher value for upper than for lower, you can use a lower "upper" than "lower" and this will still work, producing an int between the two bounds.- Specified by:
nextIntin interfaceRandomGenerator- Overrides:
nextIntin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
lower- the lower bound, inclusive, can be positive or negativeupper- the upper bound, exclusive, can be positive or negative, usually should be greater than lower- Returns:
- a random int between lower (inclusive) and upper (exclusive)
-
nextLong
public long nextLong(long bound) Exclusive on the outer bound; the inner bound is 0. The bound may be negative, which will produce a non-positive result.- Specified by:
nextLongin interfaceRandomGenerator- Overrides:
nextLongin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
bound- the outer exclusive bound; may be positive or negative- Returns:
- a random long between 0 (inclusive) and bound (exclusive)
-
nextLong
public long nextLong(long inner, long outer) Inclusive inner, exclusive outer; both inner and outer can be positive or negative.- Specified by:
nextLongin interfaceRandomGenerator- Overrides:
nextLongin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
inner- the inner bound, inclusive, can be positive or negativeouter- the outer bound, exclusive, can be positive or negative and may be greater than or less than inner- Returns:
- a random long that may be equal to inner and will otherwise be between inner and outer
-
nextDouble
public double nextDouble()Gets a uniform random double in the range [0.0,1.0)- Specified by:
nextDoublein interfaceRandomGenerator- Overrides:
nextDoublein classLegacyRandom- Returns:
- a random double at least equal to 0.0 and less than 1.0
-
nextDouble
public double nextDouble(double outer) Gets a uniform random double in the range [0.0,outer) given a positive parameter outer. If outer is negative, it will be the (exclusive) lower bound and 0.0 will be the (inclusive) upper bound.- Specified by:
nextDoublein interfaceRandomGenerator- Overrides:
nextDoublein classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
outer- the exclusive outer bound, can be negative- Returns:
- a random double between 0.0 (inclusive) and outer (exclusive)
-
nextFloat
public float nextFloat()Gets a uniform random float in the range [0.0,1.0)- Specified by:
nextFloatin interfaceRandomGenerator- Overrides:
nextFloatin classLegacyRandom- Returns:
- a random float at least equal to 0.0 and less than 1.0
-
nextBoolean
public boolean nextBoolean()Gets a random value, true or false. Calls nextLong() once.- Specified by:
nextBooleanin interfaceRandomGenerator- Overrides:
nextBooleanin classcom.github.tommyettinger.random.EnhancedRandom- Returns:
- a random true or false value.
-
nextBytes
public void nextBytes(byte[] bytes) Given a byte array as a parameter, this will fill the array with random bytes (modifying it in-place). Calls nextLong()Math.ceil(bytes.length / 8.0)times.- Specified by:
nextBytesin interfaceRandomGenerator- Overrides:
nextBytesin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
bytes- a byte array that will have its contents overwritten with random bytes.
-
setSeed
public void setSeed(long seed) Sets the seed of this generator (which is also the current state).- Specified by:
setSeedin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
seed- the seed to use for this LightRNG, as if it was constructed with this seed.
-
setState
public void setState(long seed) Sets the seed (also the current state) of this generator.- Specified by:
setStatein interfaceStatefulRandomness- Overrides:
setStatein classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
seed- the seed to use for this LightRNG, as if it was constructed with this seed.
-
getState
public long getState()Gets the current state of this generator.- Specified by:
getStatein interfaceStatefulRandomness- Returns:
- the current seed of this LightRNG, changed once per call to nextLong()
-
getStateCount
public int getStateCount()- Overrides:
getStateCountin classcom.github.tommyettinger.random.EnhancedRandom
-
getSelectedState
public long getSelectedState(int selection) - Overrides:
getSelectedStatein classcom.github.tommyettinger.random.EnhancedRandom
-
setSelectedState
public void setSelectedState(int selection, long value) - Overrides:
setSelectedStatein classcom.github.tommyettinger.random.EnhancedRandom
-
skip
public long skip(long advance) Advances or rolls back the LightRNG's state without actually generating each number. Skips forward or backward a number of steps specified by advance, where a step is equal to one call to nextLong(), and returns the random number produced at that step (you can get the state withgetState()).- Overrides:
skipin classcom.github.tommyettinger.random.EnhancedRandom- Parameters:
advance- Number of future generations to skip over; can be negative to backtrack, 0 gets the most recent generated number- Returns:
- the random long generated after skipping advance numbers
-
toString
-
equals
-
hashCode
-
determine
public static long determine(long state) -
determine
public static long determine(int a, int b) -
determineBounded
public static int determineBounded(long state, int bound) -
determineFloat
public static float determineFloat(long state) Returns a random float that is deterministic based on state; if state is the same on two calls to this, this will return the same float. This is expected to be called with a changing variable, e.g.determine(++state), where the increment for state should be odd but otherwise doesn't really matter. This multiplies state by0x9E3779B97F4A7C15Lwithin this method, so using a small increment won't be much different from using a very large one, as long as it is odd. The period is 2 to the 64 if you increment or decrement by 1, but there are only 2 to the 30 possible floats between 0 and 1.- Parameters:
state- a variable that should be different every time you want a different random result; usingdetermine(++state)is recommended to go forwards ordetermine(--state)to generate numbers in reverse order- Returns:
- a pseudo-random float between 0f (inclusive) and 1f (exclusive), determined by
state
-
determineDouble
public static double determineDouble(long state) Returns a random double that is deterministic based on state; if state is the same on two calls to this, this will return the same float. This is expected to be called with a changing variable, e.g.determine(++state), where the increment for state should be odd but otherwise doesn't really matter. This multiplies state by0x9E3779B97F4A7C15Lwithin this method, so using a small increment won't be much different from using a very large one, as long as it is odd. The period is 2 to the 64 if you increment or decrement by 1, but there are only 2 to the 62 possible doubles between 0 and 1.- Parameters:
state- a variable that should be different every time you want a different random result; usingdetermine(++state)is recommended to go forwards ordetermine(--state)to generate numbers in reverse order- Returns:
- a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive), determined by
state
-