public class ThrustAltRNG extends java.lang.Object implements StatefulRandomness, SkippingRandomness, java.io.Serializable
LightRNG
, this changes its state with a steady fixed increment, and does hash-like adjustments to the
current state to randomize it (the change is not a cipher because it is not reversible; this may be an advantage
for some usage). The period on ThrustAltRNG is 2 to the 64. ThrustAltRNG is very strong on speed, outpacing the
default generator for RNG
, DiverRNG
, by a small margin, and most other RandomnessSources in
SquidLib by a larger margin (it is slower than MiniMover64RNG
, but this has a better period). Similarly to
other hash-like PRNGs such as LightRNG
, ThrustAltRNG has a determine(long)
method that takes a state
as a long and returns a deterministic random number (each input has one output, though in this case the reverse isn't
true and some outputs will be returned by multiple inputs). Like LightRNG, but unlike an LCG such as
Random
, changing the seed even slightly generally produces completely different results, which
applies primarily to determine() but also the first number generated in a series of nextLong() calls. This generator
is GWT-safe but will be much slower on GWT than generators designed for usage there, such as GWTRNG
or
Lathe32RNG
.
Random
), but only after 16TB of data has been analyzed. Even
if using a version before the shift was changed on June 8, 2019, the quality is probably fine.
Modifier and Type | Field and Description |
---|---|
long |
state
Can be any long value.
|
Constructor and Description |
---|
ThrustAltRNG()
Creates a new generator seeded using Math.random.
|
ThrustAltRNG(long seed) |
Modifier and Type | Method and Description |
---|---|
ThrustAltRNG |
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.
|
static long |
determine(long state)
Returns a random permutation of state; if state is the same on two calls to this, this will return the same
number.
|
static int |
determineBounded(long state,
int bound)
Given a state that should usually change each time this is called, and a bound that limits the result to some
(typically fairly small) int, produces a pseudo-random int between 0 and bound (exclusive).
|
static int |
determineBoundedShort(int state,
int bound)
Given an int state that should usually change each time this is called, and a bound that limits the result to
some (typically fairly small) int, produces a pseudo-random int between 0 and bound (exclusive).
|
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.
|
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.
|
static float |
determineFloatFromInt(int state)
Returns a random float that is deterministic based on an int state; if state is the same on two calls to this,
this will return the same float.
|
static int |
determineInt(int state)
Returns a random permutation of state; if state is the same on two calls to this, this will return the same
number.
|
boolean |
equals(java.lang.Object o) |
long |
getState()
Get the current internal state of the StatefulRandomness as a long.
|
int |
hashCode() |
int |
next(int bits)
Using this method, any algorithm that might use the built-in Java Random
can interface with this randomness source.
|
long |
nextLong()
Using this method, any algorithm that needs to efficiently generate more
than 32 bits of random data can interface with this randomness source.
|
void |
setState(long state)
Set the current internal state of this StatefulRandomness with a long.
|
long |
skip(long advance)
Advances or rolls back the ThrustAltRNG's state without actually generating each number.
|
java.lang.String |
toString() |
public ThrustAltRNG()
public ThrustAltRNG(long seed)
public long getState()
getState
in interface StatefulRandomness
public void setState(long state)
setState
in interface StatefulRandomness
state
- a 64-bit longpublic int next(int bits)
next
in interface RandomnessSource
bits
- the number of bits to be returnedpublic long nextLong()
Get a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive).
nextLong
in interface RandomnessSource
public long skip(long advance)
getState()
).skip
in interface SkippingRandomness
advance
- Number of future generations to skip over; can be negative to backtrack, 0 gets the most-recently-generated numberadvance
numberspublic ThrustAltRNG copy()
copy
in interface RandomnessSource
copy
in interface StatefulRandomness
public java.lang.String toString()
toString
in class java.lang.Object
public boolean equals(java.lang.Object o)
equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object
public static long determine(long state)
determine(++state)
, where
the increment for state should be odd but otherwise doesn't really matter. This multiplies state by
0x6C8E9CF570932BD5L
within 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.state
- a variable that should be different every time you want a different random result;
using determine(++state)
is recommended to go forwards or determine(--state)
to
generate numbers in reverse orderpublic static float determineFloat(long state)
determine(++state)
,
where the increment for state should be odd but otherwise doesn't really matter. This multiplies state by
0x6C8E9CF570932BD5L
within 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.state
- a variable that should be different every time you want a different random result;
using determine(++state)
is recommended to go forwards or determine(--state)
to
generate numbers in reverse orderstate
public static double determineDouble(long state)
determine(++state)
, where the increment for state should be odd but otherwise doesn't really matter. This
multiplies state by 0x6C8E9CF570932BD5L
within 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.state
- a variable that should be different every time you want a different random result;
using determine(++state)
is recommended to go forwards or determine(--state)
to
generate numbers in reverse orderstate
public static int determineBounded(long state, int bound)
determineBounded(++state, bound)
to get a different int each time.
The period is usually 2 to the 64 when you increment or decrement by 1, but some bounds may reduce the period (in
the extreme case, a bound of 1 would force only 0 to be generated, so that would make the period 1).state
- a variable that should be different every time you want a different random result;
using determineBounded(++state, bound)
is recommended to go forwards or
determineBounded(--state, bound)
to generate numbers in reverse orderbound
- the outer exclusive bound for the int this produces; can be negative or positivepublic static int determineInt(int state)
determine(state = state + 1 | 0)
,
where the increment for state should be odd but otherwise doesn't really matter (the | 0
is needed to
force overflow to occur correctly on GWT; if you know you won't target GWT you can use determine(++state)
instead). This multiplies state by 0x62BD5
within 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 32 if you increment or
decrement by 1 (and perform any bitwise operation, such as | 0
, if you might target GWT). If you use this
on GWT and don't perform a bitwise operation on the new value for state, then the period will gradually shrink as
precision is lost by the JavaScript double that GWT will use for state as a Java int. If you know that state will
start at 0 and you call with determine(++state)
, then on GWT you may not have to worry at all until 2 to
the 34 calls have been made, after which state may cease to have the precision to represent an increase by 1 when
the math inside this method is considered. The period will have been exhausted by that point anyway (4 times), so
it's more of a concern if state may start at a much higher int.
state
- a variable that should be different every time you want a different random result;
using determine(state = state + 1 | 0)
is recommended to go forwards or
determine(state = state - 1 | 0)
to generate numbers in reverse orderpublic static int determineBoundedShort(int state, int bound)
determineBounded(++state, bound)
to get a different int each time. The period is usually 2 to the 64 when
you increment or decrement by 1, but some bounds may reduce the period (in the extreme case, a bound of 1 would
force only 0 to be generated, so that would make the period 1).
state
- an int variable that should be different every time you want a different random result;
using determineBounded(++state, bound)
is recommended to go forwards or
determineBounded(--state, bound)
to generate numbers in reverse orderbound
- the outer exclusive bound for the int this produces; should be between -65536 and 65535, inclusivepublic static float determineFloatFromInt(int state)
determine(++state)
, where the increment for state should be odd but otherwise doesn't really matter. This
multiplies state by 0x62BD5
within 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 32 if you increment or decrement by 1, but
there are only 2 to the 30 possible floats between 0 and 1, and this can generate less than 2 to the 24 of them.
state
- an int variable that should be different every time you want a different random result;
using determine(++state)
is recommended to go forwards or determine(--state)
to
generate numbers in reverse orderstate
Copyright © Eben Howard 2012–2022. All rights reserved.