/** * Seeds this DeckRNG using the RandomnessSource it is given. Does not assign the RandomnessSource to any fields * that would affect future pseudo-random number generation. * @param random will be used to generate a new seed, but will not be assigned as this object's RandomnessSource */ public DeckRNG(RandomnessSource random) { this(random.nextLong()); }
/** * This returns a random double between 0.0 (inclusive) and outer (exclusive). The value for outer can be positive * or negative. Because of how math on doubles works, there are at most 2 to the 53 values this can return for any * given outer bound, and very large values for outer will not necessarily produce all numbers you might expect. * * @param outer the outer exclusive bound as a double; can be negative or positive * @return a double between 0.0 (inclusive) and outer (exclusive) */ @Override public double nextDouble(final double outer) { return (random.nextLong() & 0x1fffffffffffffL) * 0x1p-53 * outer; }
/** * Gets a random double between 0.0 inclusive and 1.0 exclusive. * This returns a maximum of 0.9999999999999999 because that is the largest double value that is less than 1.0 . * * @return a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive) */ @Override public double nextDouble() { return (random.nextLong() & 0x1fffffffffffffL) * 0x1p-53; //this is here for a record of another possibility; it can't generate quite a lot of possible values though //return Double.longBitsToDouble(0x3FF0000000000000L | random.nextLong() >>> 12) - 1.0; }
/** * Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive). * * @return a 64-bit random long. */ @Override public long nextLong() { return random.nextLong(); }
/** * Gets a random double between 0.0 inclusive and 1.0 inclusive. * * @return a double between 0.0 (inclusive) and 1.0 (inclusive) */ public double nextDoubleInclusive() { return (random.nextLong() & 0x1fffffffffffffL) * 0x1.0000000000001p-53; }
/** * This returns a random double between 0.0 (inclusive) and outer (inclusive). The value for outer can be positive * or negative. Because of how math on doubles works, there are at most 2 to the 53 values this can return for any * given outer bound, and very large values for outer will not necessarily produce all numbers you might expect. * * @param outer the outer inclusive bound as a double; can be negative or positive * @return a double between 0.0 (inclusive) and outer (inclusive) */ public double nextDoubleInclusive(final double outer) { return (random.nextLong() & 0x1fffffffffffffL) * 0x1.0000000000001p-53 * outer; }
/** * Returns the next pseudorandom, uniformly distributed {@code long} * value from this random number generator's sequence. The general * contract of {@code nextLong} is that one {@code long} value is * pseudorandomly generated and returned. * * @return the next pseudorandom, uniformly distributed {@code long} * value from this random number generator's sequence */ @Override public long nextLong() { return randomnessSource.nextLong(); } }
/** * Generate a random double, altered to try to match the expected average and centrality. * @return a double between 0.0 (inclusive) and 1.0 (exclusive) */ @Override public double nextDouble() { return offset + range * ((centralityCalculated > (random.nextLong() & 0xfffffffffffffL) ? ((random.nextLong() & 0xfffffffffffffL) - (random.nextLong() & 0xfffffffffffffL)) * 0x1p-53 + 0.5 : twist(((random.nextLong() & 0xfffffffffffffL) - (random.nextLong() & 0xfffffffffffffL)) * 0x1p-52))); }
/** * Generates random bytes and places them into the given byte array, modifying it in-place. * The number of random bytes produced is equal to the length of the byte array. Unlike the * method in java.util.Random, this generates 8 bytes at a time, which can be more efficient * with many RandomnessSource types than the JDK's method that generates 4 bytes at a time. * <br> * Adapted from code in the JavaDocs of {@link Random#nextBytes(byte[])}. * <br> * @param bytes the byte array to fill with random bytes; cannot be null, will be modified * @throws NullPointerException if the byte array is null */ public void nextBytes(final byte[] bytes) { for (int i = 0; i < bytes.length; ) for (long r = random.nextLong(), n = Math.min(bytes.length - i, 8); n-- > 0; r >>>= 8) bytes[i++] = (byte) r; }
@Override public double nextDouble() { return NumberTools.formCurvedDouble(random.nextLong()) * 0.875 + 0.5 + luck; }
@Override public boolean nextBoolean() { return NumberTools.formCurvedFloat(random.nextLong()) * 0.875f + 0.5f + luck >= 0f; }
@Override public double nextDouble(double max) { return (NumberTools.formCurvedDouble(random.nextLong()) * 0.875 + 0.5 + luck) * max; }
@Override public float nextFloat() { return NumberTools.formCurvedFloat(random.nextLong()) * 0.875f + 0.5f + luck; }
public StatefulRNG(RandomnessSource random) { super((random instanceof StatefulRandomness) ? random : new DiverRNG(random.nextLong())); }
@Override public long nextLong(long bound) { return longify((NumberTools.formCurvedDouble(random.nextLong()) * 0.875 + 0.5 + luck) * bound); }
@Override public int nextIntHasty(int bound) { return intify((NumberTools.formCurvedDouble(random.nextLong()) * 0.875 + 0.5 + luck) * bound); }
@Override public long nextLong() { return longify((NumberTools.formCurvedDouble(random.nextLong()) + luck * -2.0) * 0x8000000000000000L); }
@Override public int nextInt(int bound) { return intify((NumberTools.formCurvedDouble(random.nextLong()) * 0.875 + 0.5 + luck) * bound); }
@Override public int nextInt() { return intify((NumberTools.formCurvedDouble(random.nextLong()) + luck * -2.0) * 0x80000000); }
@Override public void setRandomness(RandomnessSource random) { super.setRandomness(random == null ? new DiverRNG() : (random instanceof StatefulRandomness) ? random : new DiverRNG(random.nextLong())); }