public class MiniMover64RNG extends java.lang.Object implements RandomnessSource, java.io.Serializable
seed(int)
have
a minimum period of 2 to the 20, or roughly one million. It also can pass TestU01's BigCrush suite in both forward
and reversed bit order, though not for all seeds (as expected).
nextLong()
method is extremely small (as are all of the methods that use it as a
basis), which may help with inlining decisions for HotSpot. Generating the next step just needs a bitwise rotation of
the current state, multiplying the result by a 32-bit constant, and assigning that to state. Generating a long after
that only needs a multiplication by another constant, which doesn't have the issues with reversed-bits testing that
some other generators do when they multiply as their only output step (xorshift128 notably has patterns in its low
bits, so multiplying by a constant doesn't help those bits, but the CMR generator here has no such low-bit problems).
This means only three math instructions need to be performed to get a new random number (bitwise rotate left,
multiply, multiply), which is extremely low for a high-quality generator. While the CMR state change does not
pipeline well, the ease of calculating a complete number seems to make up for it on desktop JVMs.
Math.pow(2, 25)
and
validated that each of their periods is at least Math.pow(2, 20) - 1
. This means that as long as a period
as low as 1 million is rarely allowed, a starting state can be quickly chosen from a 32-bit int by using the bottom
25 bits of the int (plus 1, to disallow the 0 state) and using the remaining 7 bits to step up to 127 times through
the generator.
Mover64RNG
, has a shorter period than
it, and is faster than it in all aspects.
Constructor and Description |
---|
MiniMover64RNG()
Calls
seed(int) with a random int value (obtained using Math.random() ). |
MiniMover64RNG(int state)
The recommended constructor, this guarantees the generator will have a period of at least 2 to the 20 (roughly
one million, but most if not all initial states will have much longer periods).
|
MiniMover64RNG(long state)
Not advised for external use; prefer
MiniMover64RNG(int) because it guarantees a good subcycle. |
Modifier and Type | Method and Description |
---|---|
MiniMover64RNG |
copy()
Produces a copy of this MiniMover64RNG 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.
|
boolean |
equals(java.lang.Object o) |
long |
getState()
Gets the state; if this generator was set with
MiniMover64RNG() ,
MiniMover64RNG(int) , or seed(int) , then this will be on a good subcycle, otherwise it
may not be. |
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.
|
double |
nextDouble()
Gets a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive).
|
float |
nextFloat()
Gets a pseudo-random float between 0.0f (inclusive) and 1.0f (exclusive).
|
int |
nextInt() |
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 |
seed(int s)
Seeds the state using all bits of the given int
s . |
void |
setState(long state)
Sets the state to any long, which may put the generator in a low-period subcycle.
|
java.lang.String |
toString() |
public MiniMover64RNG()
seed(int)
with a random int value (obtained using Math.random()
).public MiniMover64RNG(int state)
state
.state
- any int; will be used to get the actual state used in the generator (which is a long internally)public MiniMover64RNG(long state)
MiniMover64RNG(int)
because it guarantees a good subcycle. This
constructor allows all subcycles to be produced, including ones with a shorter period.state
- the state to use, exactly unless it is 0 (then this uses 1)public void seed(int s)
s
. Between 33554432 and 4294967296 seeds are possible,
with the actual count probably much closer to 4294967296. This treats the bottom 25 bits of s
(plus 1, to
avoid a seed of 0) as the starting point and then generates the next state at most 127 times, with
each generated state taking less time than nextLong()
. Some of the starting states are entirely possible
to be within 127 steps of another starting state, so not all seeds are necessarily unique. This is not
guaranteed to put the generator on an optimal subcycle, but it is guaranteed that any subcycle will have a period
of at least 1048575.s
- all bits are used, none verbatim (0 is tolerated)public int nextInt()
public int next(int bits)
RandomnessSource
next
in interface RandomnessSource
bits
- the number of bits to be returnedpublic long nextLong()
RandomnessSource
nextLong
in interface RandomnessSource
public double nextDouble()
public float nextFloat()
public MiniMover64RNG copy()
copy
in interface RandomnessSource
public long getState()
MiniMover64RNG()
,
MiniMover64RNG(int)
, or seed(int)
, then this will be on a good subcycle, otherwise it
may not be.public void setState(long state)
seed(int)
to guarantee a good subcycle.state
- any intpublic 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
Copyright © Eben Howard 2012–2022. All rights reserved.