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

src.it.unimi.dsi.util.XorShift64StarRandom Maven / Gradle / Ivy

Go to download

The DSI utilities are a mishmash of classes accumulated during the last twenty years in projects developed at the DSI (Dipartimento di Scienze dell'Informazione, i.e., Information Sciences Department), now DI (Dipartimento di Informatica, i.e., Informatics Department), of the Universita` degli Studi di Milano.

There is a newer version: 2.7.3
Show newest version
package it.unimi.dsi.util;

/*
 * DSI utilities
 *
 * Copyright (C) 2011-2020 Sebastiano Vigna
 *
 *  This library is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU Lesser General Public License as published by the Free
 *  Software Foundation; either version 3 of the License, or (at your option)
 *  any later version.
 *
 *  This library is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, see .
 *
 */


import it.unimi.dsi.Util;
import it.unimi.dsi.fastutil.HashCommon;

import java.util.Random;

/** A fast, good-quality {@linkplain Random pseudorandom number generator}
 * that combines George Marsaglia's Xorshift
 * generators (described in “Xorshift RNGs”,
 * Journal of Statistical Software, 8:1−6, 2003) with a multiplication.
 *
 * @deprecated Use {@link SplitMix64Random} instead.
 */
@Deprecated
public class XorShift64StarRandom extends Random {
	private static final long serialVersionUID = 1L;

	/** The internal state of the algorithm. */
	private long x;

	/** Creates a new generator seeded using {@link Util#randomSeed()}. */
	public XorShift64StarRandom() {
		this(Util.randomSeed());
	}

	/** Creates a new generator using a given seed.
	 *
	 * @param seed a nonzero seed for the generator (if zero, the generator will be seeded with {@link Long#MIN_VALUE}).
	 */
	public XorShift64StarRandom(final long seed) {
		super(seed);
	}

	@Override
	protected int next(int bits) {
		return (int)(nextLong() & (1L << bits) - 1);
	}

	@Override
	public long nextLong() {
		x ^= x >>> 12;
		x ^= x << 25;
		return 2685821657736338717L * (x ^= (x >>> 27));
	}

	@Override
	public int nextInt() {
		return (int)nextLong();
	}

	/** Returns a pseudorandom, approximately uniformly distributed {@code int} value
     * between 0 (inclusive) and the specified value (exclusive), drawn from
     * this random number generator's sequence.
     *
     * 

The hedge “approximately” is due to the fact that to be always * faster than ThreadLocalRandom * we return * the upper 63 bits of {@link #nextLong()} modulo {@code n} instead of using * {@link Random}'s fancy algorithm (which {@link #nextLong(long)} uses though). * This choice introduces a bias: the numbers from 0 to 263 mod {@code n} * are slightly more likely than the other ones. In the worst case, “more likely” * means 1.00000000023 times more likely, which is in practice undetectable (actually, * due to the abysmally low quality of {@link Random}'s generator, the result is statistically * better in any case than {@link Random#nextInt(int)}'s) . * *

If for some reason you need truly uniform generation, just use {@link #nextLong(long)}. * * @param n the positive bound on the random number to be returned. * @return the next pseudorandom {@code int} value between {@code 0} (inclusive) and {@code n} (exclusive). */ @Override public int nextInt(final int n) { if (n <= 0) throw new IllegalArgumentException(); // No special provision for n power of two: all our bits are good. return (int)((nextLong() >>> 1) % n); } /** Returns a pseudorandom 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. * * @param n the positive bound on the random number to be returned. * @return the next pseudorandom {@code long} value between {@code 0} (inclusive) and {@code n} (exclusive). */ public long nextLong(final long n) { if (n <= 0) throw new IllegalArgumentException(); // No special provision for n power of two: all our bits are good. for(;;) { final long bits = nextLong() >>> 1; final long value = bits % n; if (bits - value + (n - 1) >= 0) return value; } } @Override public double nextDouble() { return (nextLong() >>> 11) * 0x1.0p-53; } @Override public float nextFloat() { return (nextLong() >>> 40) * 0x1.0p-24f; } @Override public boolean nextBoolean() { return nextLong() < 0; } @Override public void nextBytes(final byte[] bytes) { int i = bytes.length, n = 0; while(i != 0) { n = Math.min(i, 8); for (long bits = nextLong(); n-- != 0; bits >>= 8) bytes[--i] = (byte)bits; } } /** Sets the seed of this generator. * *

The seed will be passed through {@link HashCommon#murmurHash3(long)}. In this way, if the * user passes a small value we will avoid the short irregular transient associated * with states with 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) { x = HashCommon.murmurHash3(seed == 0 ? Long.MIN_VALUE : seed); } /** Sets the state of this generator. * * @param state the new state for this generator (must be nonzero). */ public void setState(final long state) { x = (state == 0 ? -1 : state); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy