public class GWTRNG extends AbstractRNG implements IStatefulRNG, java.io.Serializable
Starfish32RNG
, which means it has two 32-bit ints for
state and a period of 0xFFFFFFFFFFFFFFFF (2 to the 64 minus 1), while passing 32TB of PractRand tests without any
failures or anomalies (so its quality is very good). This previously used Lathe32RNG
's algorithm, which is a
tiny bit faster on desktop and a fair amount faster on GWT, but can't produce all long values and produces some more
often than others. Unlike RNG
, there is no RandomnessSource that can be swapped out, but also somewhat less
indirection on common calls like nextInt()
and nextFloat()
. Although this implements
StatefulRandomness
, it is not recommended to use this as the RandomnessSource for a StatefulRNG; you should
use Starfish32RNG
if you want the larger API provided by StatefulRNG and/or RNG while keeping similar, though
probably slightly weaker, GWT performance relative to this class. Any performance measurements on GWT depend heavily
on the browser; in some versions of Chrome and Chromium, this performs almost exactly as well as Lathe32RNG, but in
newer versions it lags behind by a small factor. It tends to be very fast in the current Firefox (September 2018).
0x9E3779BD
from every output, that modified output will fail some tests reliably.
Similar numbers may also cause this result, though it isn't clear if this is ever relevant in actual usage. Part of
the reason Lathe32RNG was switched out was because its behavior on AbstractRNG.between(int, int)
was poor, but it
doesn't seem to be for this version.
Constructor and Description |
---|
GWTRNG()
Creates a new generator seeded using two calls to Math.random().
|
GWTRNG(int seed)
Constructs this GWTRNG by dispersing the bits of seed using
setSeed(int) across the two parts of state
this has. |
GWTRNG(int stateA,
int stateB)
Constructs this GWTRNG by calling
setState(int, int) on stateA and stateB as given; see that method
for the specific details (stateA and stateB are kept as-is unless they are both 0). |
GWTRNG(long seed)
Constructs this GWTRNG by splitting the given seed across the two parts of state this has with
setState(long) . |
GWTRNG(java.lang.String seed)
Hashes
seed using both CrossHash.hash(CharSequence) and String.hashCode() and uses those
two results as the two states with setState(int, int) . |
Modifier and Type | Method and Description |
---|---|
GWTRNG |
copy()
Creates a copy of this GWTRNG; it will generate the same random numbers, given the same calls in order, as this
GWTRNG at the point copy() is called.
|
static long |
determine(int state)
A deterministic random long generator that, given one int
state as input, returns an
almost-always-different long as a result. |
static int |
determineBounded(int state,
int bound)
A deterministic random int generator that, given one int
state and an outer int bound as input,
returns an int between 0 (inclusive) and bound (exclusive) as a result, which should have no noticeable
correlation between state and the result. |
static double |
determineDouble(int state)
A deterministic random double generator that, given one int
state as input, returns an
almost-always-different double between 0.0 and 1.0 as a result. |
static float |
determineFloat(int state)
A deterministic random float generator that, given one int
state as input, returns an
almost-always-different float between 0.0f and 1.0f as a result. |
static int |
determineInt(int state)
A deterministic random int generator that, given one int
state as input, irreversibly returns an
almost-always-different int as a result. |
boolean |
equals(java.lang.Object o) |
long |
getState()
Get the current internal state of the StatefulRandomness as a long.
|
int |
getStateA() |
int |
getStateB() |
int |
hashCode() |
int |
next(int bits)
Get up to 32 bits (inclusive) of random output; the int this produces
will not require more than
bits bits to represent. |
boolean |
nextBoolean()
Get a random bit of state, interpreted as true or false with approximately equal likelihood.
|
double |
nextDouble()
Gets a random double between 0.0 inclusive and 1.0 exclusive.
|
float |
nextFloat()
Gets a random float between 0.0f inclusive and 1.0f exclusive.
|
int |
nextInt()
Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).
|
int |
nextInt(int bound)
Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or
negative.
|
long |
nextLong()
Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).
|
void |
setSeed(int seed)
Sets the state of this generator using one int, running it through Zog32RNG's algorithm two times to get
two ints.
|
void |
setState(int stateA,
int stateB)
Sets the current internal state of this GWTRNG with three ints, where stateA and stateB can each be any int
unless they are both 0 (which will be treated as if stateA is 1 and stateB is 0).
|
void |
setState(long state)
Set the current internal state of this StatefulRandomness with a long.
|
void |
setStateA(int stateA)
Sets the first part of the state to the given int.
|
void |
setStateB(int stateB)
Sets the second part of the state to the given int.
|
java.io.Serializable |
toSerializable()
Gets a view of this IRNG in a way that implements
Serializable , which is simply this IRNG. |
java.lang.String |
toString() |
between, between, between, getRandomElement, getRandomElement, getRandomElement, nextDouble, nextFloat, nextLong, nextSignedInt, nextSignedLong, randomOrdering, randomOrdering, randomPortion, shuffle, shuffle, shuffle, shuffle, shuffleInPlace, shuffleInPlace, swap
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
between, between, between, getRandomElement, getRandomElement, getRandomElement, nextDouble, nextFloat, nextLong, nextSignedInt, nextSignedLong, randomOrdering, randomOrdering, randomPortion, shuffle, shuffle, shuffle, shuffle, shuffleInPlace, shuffleInPlace
public GWTRNG()
public GWTRNG(int seed)
setSeed(int)
across the two parts of state
this has.seed
- an int that won't be used exactly, but will affect both components of statepublic GWTRNG(long seed)
setState(long)
.seed
- a long that will be split across both components of statepublic GWTRNG(int stateA, int stateB)
setState(int, int)
on stateA and stateB as given; see that method
for the specific details (stateA and stateB are kept as-is unless they are both 0).stateA
- the number to use as the first part of the state; this will be 1 instead if both seeds are 0stateB
- the number to use as the second part of the statepublic GWTRNG(java.lang.String seed)
seed
using both CrossHash.hash(CharSequence)
and String.hashCode()
and uses those
two results as the two states with setState(int, int)
. If seed is null, this won't call
String.hashCode() on it and will instead use 1 as that state (to avoid the forbidden double-zero case).seed
- any String; may be nullpublic int next(int bits)
bits
bits to represent.next
in interface IRNG
next
in interface RandomnessSource
next
in class AbstractRNG
bits
- an int between 1 and 32, both inclusivepublic int nextInt()
nextInt
in interface IRNG
nextInt
in class AbstractRNG
public int nextInt(int bound)
nextInt
in interface IRNG
nextInt
in class AbstractRNG
bound
- the upper bound (exclusive)public long nextLong()
nextLong
in interface IRNG
nextLong
in interface RandomnessSource
nextLong
in class AbstractRNG
public boolean nextBoolean()
nextBoolean
in interface IRNG
nextBoolean
in class AbstractRNG
public double nextDouble()
nextDouble
in interface IRNG
nextDouble
in class AbstractRNG
public float nextFloat()
nextFloat
in interface IRNG
nextFloat
in class AbstractRNG
public GWTRNG copy()
copy
in interface RandomnessSource
copy
in interface StatefulRandomness
copy
in class AbstractRNG
public java.io.Serializable toSerializable()
Serializable
, which is simply this IRNG.toSerializable
in interface IRNG
toSerializable
in class AbstractRNG
Serializable
view of this IRNG or a similar one; always this
public void setSeed(int seed)
seed
- the int to use to produce this generator's statepublic int getStateA()
public void setStateA(int stateA)
setState(int, int)
to set both states at once, but the result will be the same if you call
setStateA() and then setStateB() or if you call setStateB() and then setStateA().stateA
- any intpublic int getStateB()
public void setStateB(int stateB)
setState(int, int)
to set both states at once, but the result will be the same if you call
setStateA() and then setStateB() or if you call setStateB() and then setStateA().stateB
- any intpublic void setState(int stateA, int stateB)
stateA
- any int (if stateA and stateB are both 0, this will be treated as 1)stateB
- any intpublic long getState()
getState
in interface StatefulRandomness
public void setState(long state)
setState
in interface StatefulRandomness
state
- a 64-bit long. You should avoid passing 0; this implementation will treat it as 1.public boolean equals(java.lang.Object o)
equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object
public java.lang.String toString()
toString
in class java.lang.Object
public static int determineInt(int state)
state
as input, irreversibly returns an
almost-always-different int as a result. Unlike the rest of GWTRNG, this will not produce all possible ints given
all ints as inputs, and probably a third of all possible ints cannot be returned. You should call this with
GWTRNG.determineInt(state = state + 1 | 0)
(you can subtract 1 to go backwards instead of forwards),
which will allow overflow in the incremented state to be handled the same on GWT as on desktop.state
- an int that should go up or down by 1 each call, as with GWTRNG.determineInt(state = state + 1 | 0)
to handle overflowstate
public static int determineBounded(int state, int bound)
state
and an outer int bound
as input,
returns an int between 0 (inclusive) and bound
(exclusive) as a result, which should have no noticeable
correlation between state
and the result. You should call this with
GWTRNG.determineBound(state = state + 1 | 0, bound)
(you can subtract 1 to go backwards instead of
forwards), which will allow overflow in the incremented state to be handled the same on GWT as on desktop.
Like most bounded int generation in SquidLib, this uses some long math, but most of the function uses ints.state
- an int that should go up or down by 1 each call, as with GWTRNG.determineBounded(state = state + 1 | 0, bound)
to handle overflowbound
- the outer exclusive bound, as an int; may be positive or negativebound
(exclusive)public static long determine(int state)
state
as input, returns an
almost-always-different long as a result. This can only return a tiny fraction of all possible longs, since there
are at most 2 to the 32 possible ints and this doesn't even return different values for each of those. You should
call this with GWTRNG.determine(state = state + 1 | 0)
(you can subtract 1 to go backwards instead of
forwards), which will allow overflow in the incremented state to be handled the same on GWT as on desktop.state
- an int that should go up or down by 1 each call, as with GWTRNG.determine(state = state + 1 | 0)
to handle overflowstate
public static float determineFloat(int state)
state
as input, returns an
almost-always-different float between 0.0f and 1.0f as a result. Unlike the rest of GWTRNG, this might not
produce all possible floats given all ints as inputs, and some fraction of possible floats cannot be returned.
You should call this with GWTRNG.determineFloat(state = state + 1 | 0)
(you can subtract 1 to go
backwards instead of forwards), which will allow overflow in the incremented state to be handled the same on GWT
as on desktop.state
- an int that should go up or down by 1 each call, as with GWTRNG.determineFloat(state = state + 1 | 0)
to handle overflowstate
public static double determineDouble(int state)
state
as input, returns an
almost-always-different double between 0.0 and 1.0 as a result. This cannot produce more than a tiny fraction of
all possible doubles because the input is 32 bits and at least 53 bits are needed to represent most doubles from
0.0 to 1.0. You should call this with GWTRNG.determineDouble(state = state + 1 | 0)
(you can subtract 1
to go backwards instead of forwards), which will allow overflow in the incremented state to be handled the same
on GWT as on desktop.state
- an int that should go up or down by 1 each call, as with GWTRNG.determineDouble(state = state + 1 | 0)
to handle overflowstate
Copyright © Eben Howard 2012–2022. All rights reserved.