All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mini2Dx.gdx.math.RandomXS128 Maven / Gradle / Ivy

There is a newer version: 1.9.13
Show newest version
/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package org.mini2Dx.gdx.math;

import java.util.Random;

/** This class implements the xorshift128+ algorithm that is a very fast, top-quality 64-bit pseudo-random number generator. The
 * quality of this PRNG is much higher than {@link Random}'s, and its cycle length is 2128 − 1, which
 * is more than enough for any single-thread application. More details and algorithms can be found here.
 * 

* Instances of RandomXS128 are not thread-safe. * * @author Inferno * @author davebaol */ public class RandomXS128 extends Random { /** Normalization constant for double. */ private static final double NORM_DOUBLE = 1.0 / (1L << 53); /** Normalization constant for float. */ private static final double NORM_FLOAT = 1.0 / (1L << 24); /** The first half of the internal state of this pseudo-random number generator. */ private long seed0; /** The second half of the internal state of this pseudo-random number generator. */ private long seed1; /** Creates a new random number generator. This constructor sets the seed of the random number generator to a value very likely * to be distinct from any other invocation of this constructor. *

* This implementation creates a {@link Random} instance to generate the initial seed. */ public RandomXS128 () { setSeed(new Random().nextLong()); } /** Creates a new random number generator using a single {@code long} seed. * @param seed the initial seed */ public RandomXS128 (long seed) { setSeed(seed); } /** Creates a new random number generator using two {@code long} seeds. * @param seed0 the first part of the initial seed * @param seed1 the second part of the initial seed */ public RandomXS128 (long seed0, long seed1) { setState(seed0, seed1); } /** Returns the next pseudo-random, uniformly distributed {@code long} value from this random number generator's sequence. *

* Subclasses should override this, as this is used by all other methods. */ @Override public long nextLong () { long s1 = this.seed0; final long s0 = this.seed1; this.seed0 = s0; s1 ^= s1 << 23; return (this.seed1 = (s1 ^ s0 ^ (s1 >>> 17) ^ (s0 >>> 26))) + s0; } /** This protected method is final because, contrary to the superclass, it's not used anymore by the other methods. */ @Override protected final int next (int bits) { return (int)(nextLong() & ((1L << bits) - 1)); } /** Returns the next pseudo-random, uniformly distributed {@code int} value from this random number generator's sequence. *

* This implementation uses {@link #nextLong()} internally. */ @Override public int nextInt () { return (int)nextLong(); } /** Returns a pseudo-random, uniformly distributed {@code int} value between 0 (inclusive) and the specified value (exclusive), * drawn from this random number generator's sequence. *

* This implementation uses {@link #nextLong()} internally. * @param n the positive bound on the random number to be returned. * @return the next pseudo-random {@code int} value between {@code 0} (inclusive) and {@code n} (exclusive). */ @Override public int nextInt (final int n) { return (int)nextLong(n); } /** Returns a pseudo-random, uniformly distributed {@code long} value between 0 (inclusive) and the specified value (exclusive), * drawn from this random number generator's sequence. The algorithm used to generate the value guarantees that the result is * uniform, provided that the sequence of 64-bit values produced by this generator is. *

* This implementation uses {@link #nextLong()} internally. * @param n the positive bound on the random number to be returned. * @return the next pseudo-random {@code long} value between {@code 0} (inclusive) and {@code n} (exclusive). */ public long nextLong (final long n) { if (n <= 0) throw new IllegalArgumentException("n must be positive"); for (;;) { final long bits = nextLong() >>> 1; final long value = bits % n; if (bits - value + (n - 1) >= 0) return value; } } /** Returns a pseudo-random, uniformly distributed {@code double} value between 0.0 and 1.0 from this random number generator's * sequence. *

* This implementation uses {@link #nextLong()} internally. */ @Override public double nextDouble () { return (nextLong() >>> 11) * NORM_DOUBLE; } /** Returns a pseudo-random, uniformly distributed {@code float} value between 0.0 and 1.0 from this random number generator's * sequence. *

* This implementation uses {@link #nextLong()} internally. */ @Override public float nextFloat () { return (float)((nextLong() >>> 40) * NORM_FLOAT); } /** Returns a pseudo-random, uniformly distributed {@code boolean } value from this random number generator's sequence. *

* This implementation uses {@link #nextLong()} internally. */ @Override public boolean nextBoolean () { return (nextLong() & 1) != 0; } /** Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the * length of the byte array. *

* This implementation uses {@link #nextLong()} internally. */ @Override public void nextBytes (final byte[] bytes) { int n = 0; int i = bytes.length; while (i != 0) { n = i < 8 ? i : 8; // min(i, 8); for (long bits = nextLong(); n-- != 0; bits >>= 8) bytes[--i] = (byte)bits; } } /** Sets the internal seed of this generator based on the given {@code long} value. *

* The given seed is passed twice through a hash function. This way, if the user passes a small value we avoid the short * irregular transient associated with states having a very small number of bits set. * @param seed a nonzero seed for this generator (if zero, the generator will be seeded with {@link Long#MIN_VALUE}). */ @Override public void setSeed (final long seed) { long seed0 = murmurHash3(seed == 0 ? Long.MIN_VALUE : seed); setState(seed0, murmurHash3(seed0)); } /** Sets the internal state of this generator. * @param seed0 the first part of the internal state * @param seed1 the second part of the internal state */ public void setState (final long seed0, final long seed1) { this.seed0 = seed0; this.seed1 = seed1; } /** * Returns the internal seeds to allow state saving. * @param seed must be 0 or 1, designating which of the 2 long seeds to return * @return the internal seed that can be used in setState */ public long getState(int seed) { return seed == 0 ? seed0 : seed1; } private final static long murmurHash3 (long x) { x ^= x >>> 33; x *= 0xff51afd7ed558ccdL; x ^= x >>> 33; x *= 0xc4ceb9fe1a85ec53L; x ^= x >>> 33; return x; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy