001/* 002Written in 2015 by Sebastiano Vigna (vigna@acm.org) 003 004To the extent possible under law, the author has dedicated all copyright 005and related and neighboring rights to this software to the public domain 006worldwide. This software is distributed without any warranty. 007 008See <http://creativecommons.org/publicdomain/zero/1.0/>. */ 009package squidpony.squidmath; 010 011import squidpony.StringKit; 012 013import java.io.Serializable; 014 015/** 016 * This is a SplittableRandom-style generator, meant to have a tiny state 017 * that permits storing many different generators with low overhead. 018 * It should be rather fast, though no guarantees can be made on all hardware. 019 * It should be faster than using SplittableRandom from Java 8 because it has a 020 * single "gamma" value that prevents it from being split but also makes runtime 021 * a bit quicker. It is based on using a unary hash on a large-increment counter, 022 * which makes even the first item obtained from similarly-seeded LightRNGs very 023 * likely to be very different. This is an advantage over non-hash-based RNGs. 024 * <br> 025 * This generator is especially fast on OpenJ9, version 0.17.0 or later (from 026 * late 2019), and can be several times faster there than on HotSpot. 027 * <br> 028 * Written in 2015 by Sebastiano Vigna (vigna@acm.org) 029 * @author Sebastiano Vigna 030 * @author Tommy Ettinger 031 */ 032public final class LightRNG implements RandomnessSource, StatefulRandomness, SkippingRandomness, Serializable 033{ 034 private static final long serialVersionUID = -374415589203474497L; 035 036 public long state; /* The state can be seeded with any value. */ 037 038 /** Creates a new generator seeded using Math.random. */ 039 public LightRNG() { 040 this((long) ((Math.random() - 0.5) * 0x10000000000000L) 041 ^ (long) (((Math.random() - 0.5) * 2.0) * 0x8000000000000000L)); 042 } 043 044 public LightRNG( final long seed ) { 045 setSeed(seed); 046 } 047 048 /** 049 * Gets a pseudo-random int with at most the specified count of bits; for example, if bits is 3 this can return any 050 * int between 0 and 2 to the 3 (that is, 8), exclusive on the upper end. That would mean 7 could be returned, but 051 * no higher ints, and 0 could be returned, but no lower ints. 052 * 053 * The algorithm used here changed on March 8, 2018 when LightRNG was remade the default generator in SquidLib. 054 * The older method is available as {@link #compatibleNext(int)}, but its use is discouraged; it's slightly slower 055 * for no good reason. 056 * @param bits the number of bits to be returned; if 0 or less, or if 32 or greater, can return any 32-bit int 057 * @return a pseudo-random int that uses at most the specified amount of bits 058 */ 059 @Override 060 public final int next( int bits ) { 061 long z = state += 0x9E3779B97F4A7C15L; 062 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 063 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 064 return (int)(z ^ (z >>> 31)) >>> (32 - bits); 065 } 066 /** 067 * Gets a pseudo-random int with at most the specified count of bits; for example, if bits is 3 this can return any 068 * int between 0 and 2 to the 3 (that is, 8), exclusive on the upper end. That would mean 7 could be returned, but 069 * no higher ints, and 0 could be returned, but no lower ints. 070 * 071 * The algorithm used here is the older version of {@link #next(int)} before some things changed on March 8 2018. 072 * Using this method is discouraged unless you need to reproduce values exactly; it's slightly slower for no good 073 * reason. Calling {@code next(32)} and {@code compatibleNext(32)} should have identical results, but other values 074 * for bits will probably be different. 075 * @param bits the number of bits to be returned; if 0 or less, or if 32 or greater, can return any 32-bit int 076 * @return a pseudo-random int that uses at most the specified amount of bits 077 */ 078 public final int compatibleNext( int bits ) { 079 long z = state += 0x9E3779B97F4A7C15L; 080 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 081 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 082 return (int)( (z ^ (z >>> 31)) & ( 1L << bits ) - 1 ); 083 } 084 /** 085 * Can return any long, positive or negative, of any size permissible in a 64-bit signed integer. 086 * @return any long, all 64 bits are random 087 */ 088 @Override 089 public final long nextLong() { 090 long z = state += 0x9E3779B97F4A7C15L; 091 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 092 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 093 return z ^ (z >>> 31); 094 } 095 096 /** 097 * Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the 098 * copy, both will generate the same sequence of random numbers from the point copy() was called. This just needs to 099 * copy the state so it isn't shared, usually, and produce a new value with the same exact state. 100 * 101 * @return a copy of this RandomnessSource 102 */ 103 @Override 104 public LightRNG copy() { 105 return new LightRNG(state); 106 } 107 108 /** 109 * Can return any int, positive or negative, of any size permissible in a 32-bit signed integer. 110 * @return any int, all 32 bits are random 111 */ 112 public int nextInt() { 113 long z = state += 0x9E3779B97F4A7C15L; 114 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 115 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 116 return (int) (z ^ (z >>> 31)); 117 } 118 119 /** 120 * Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), 121 * or 0 if the bound is 0. The bound can be negative, which will produce 0 or a negative result. 122 * Uses an aggressively optimized technique that has some bias, but mostly for values of 123 * bound over 1 billion. This method uses the same technique as {@link RNG#nextIntHasty(int)}, 124 * and like that method will always advance state exactly once (equivalent to one call to 125 * {@link #nextLong()}). 126 * <br> 127 * Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ 128 * 129 * @param bound the outer bound (exclusive), can be negative or positive 130 * @return the found number 131 */ 132 public int nextInt( final int bound ) { 133 long z = state += 0x9E3779B97F4A7C15L; 134 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 135 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 136 return (int) ((bound * ((z ^ (z >>> 31)) & 0x7FFFFFFFL)) >> 31); 137 } 138 139 /** 140 * Like {@link #compatibleNext(int)}, but for compatibility with {@link #nextInt(int)}. 141 * Exclusive on the upper bound. The lower bound is 0. 142 * @param bound the upper bound; should be positive 143 * @return a random int less than n and at least equal to 0 144 */ 145 public int compatibleNextInt( final int bound ) { 146 if (bound <= 0) return 0; 147 int threshold = (0x7fffffff - bound + 1) % bound; 148 for (; ; ) { 149 int bits = (int) (nextLong() & 0x7fffffff); 150 if (bits >= threshold) 151 return bits % bound; 152 } 153 } 154 /** 155 * Inclusive lower, exclusive upper. Although you should usually use a higher value for upper than for lower, you 156 * can use a lower "upper" than "lower" and this will still work, producing an int between the two bounds. 157 * @param lower the lower bound, inclusive, can be positive or negative 158 * @param upper the upper bound, exclusive, can be positive or negative, usually should be greater than lower 159 * @return a random int between lower (inclusive) and upper (exclusive) 160 */ 161 public int nextInt( final int lower, final int upper ) { 162 return lower + nextInt(upper - lower); 163 } 164 165 /** 166 * Inclusive lower, exclusive upper. 167 * @param lower the lower bound, inclusive, can be positive or negative 168 * @param upper the upper bound, exclusive, should be positive, must be greater than lower 169 * @return a random int between lower (inclusive) and upper (exclusive) 170 */ 171 public int compatibleNextInt( final int lower, final int upper ) { 172 if ( upper - lower <= 0 ) throw new IllegalArgumentException("Upper bound must be greater than lower bound"); 173 return lower + compatibleNextInt(upper - lower); 174 } 175 176 /** 177 * Exclusive on the outer bound; the inner bound is 0. The bound may be negative, which will produce a non-positive 178 * result. 179 * @param bound the outer exclusive bound; may be positive or negative 180 * @return a random long between 0 (inclusive) and bound (exclusive) 181 */ 182 public long nextLong(long bound) { 183 long rand = nextLong(); 184 final long randLow = rand & 0xFFFFFFFFL; 185 final long boundLow = bound & 0xFFFFFFFFL; 186 rand >>>= 32; 187 bound >>= 32; 188 final long t = rand * boundLow + (randLow * boundLow >>> 32); 189 return rand * bound + (t >> 32) + (randLow * bound + (t & 0xFFFFFFFFL) >> 32); 190 } 191 192 /** 193 * Inclusive inner, exclusive outer; both inner and outer can be positive or negative. 194 * @param inner the inner bound, inclusive, can be positive or negative 195 * @param outer the outer bound, exclusive, can be positive or negative and may be greater than or less than inner 196 * @return a random long that may be equal to inner and will otherwise be between inner and outer 197 */ 198 public long nextLong(final long inner, final long outer) { 199 return inner + nextLong(outer - inner); 200 } 201 202 203 /** 204 * Exclusive on the upper bound. The lower bound is 0. Unlike {@link #nextInt(int)} or {@link #nextLong(long)}, this 205 * may sometimes advance the state more than once, depending on what numbers are produced internally and the bound. 206 * {@link #nextLong(long)} is preferred because it is much faster and reliably advances the state only once. Because 207 * this method uses rejection sampling, getting multiple random longs to "smooth the odds" when the bound is such 208 * that it can't fairly distribute one random long across all possible outcomes, it may be more "fair" than 209 * {@link #nextLong(long)}, though it could potentially consume more of the period faster if pathologically bad 210 * bounds were used very often, and if enough of the period is gone then statistical flaws may become detectable. 211 * @param bound the upper bound; if this isn't positive, this method always returns 0 212 * @return a random long less than n and at least equal to 0 213 */ 214 public long compatibleNextLong(final long bound) { 215 if ( bound <= 0 ) return 0; 216 long threshold = (0x7fffffffffffffffL - bound + 1) % bound; 217 for (;;) { 218 long bits = nextLong() & 0x7fffffffffffffffL; 219 if (bits >= threshold) 220 return bits % bound; 221 } 222 } 223 224 /** 225 * Inclusive lower, exclusive upper. 226 * @param lower the lower bound, inclusive, can be positive or negative 227 * @param upper the upper bound, exclusive, should be positive, must be greater than lower 228 * @return a random long at least equal to lower and less than upper 229 */ 230 public long compatibleNextLong( final long lower, final long upper ) { 231 if ( upper - lower <= 0 ) throw new IllegalArgumentException("Upper bound must be greater than lower bound"); 232 return lower + compatibleNextLong(upper - lower); 233 } 234 /** 235 * Gets a uniform random double in the range [0.0,1.0) 236 * @return a random double at least equal to 0.0 and less than 1.0 237 */ 238 public double nextDouble() { 239 long z = state += 0x9E3779B97F4A7C15L; 240 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 241 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 242 return ((z ^ (z >>> 31)) & 0x1fffffffffffffL) * 0x1p-53; 243 } 244 245 /** 246 * Gets a uniform random double in the range [0.0,outer) given a positive parameter outer. If outer 247 * is negative, it will be the (exclusive) lower bound and 0.0 will be the (inclusive) upper bound. 248 * @param outer the exclusive outer bound, can be negative 249 * @return a random double between 0.0 (inclusive) and outer (exclusive) 250 */ 251 public double nextDouble(final double outer) { 252 return nextDouble() * outer; 253 } 254 255 /** 256 * Gets a uniform random float in the range [0.0,1.0) 257 * @return a random float at least equal to 0.0 and less than 1.0 258 */ 259 public float nextFloat() { 260 long z = state += 0x9E3779B97F4A7C15L; 261 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 262 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 263 return ((z ^ (z >>> 31)) & 0xffffffL) * 0x1p-24f; 264 265 } 266 267 /** 268 * Gets a random value, true or false. 269 * Calls nextLong() once. 270 * @return a random true or false value. 271 */ 272 public boolean nextBoolean() { 273 return nextLong() < 0L; 274 } 275 276 /** 277 * Given a byte array as a parameter, this will fill the array with random bytes (modifying it 278 * in-place). Calls nextLong() {@code Math.ceil(bytes.length / 8.0)} times. 279 * @param bytes a byte array that will have its contents overwritten with random bytes. 280 */ 281 public void nextBytes( final byte[] bytes ) { 282 int i = bytes.length, n; 283 while( i != 0 ) { 284 n = Math.min( i, 8 ); 285 for ( long bits = nextLong(); n-- != 0; bits >>>= 8 ) bytes[ --i ] = (byte)bits; 286 } 287 } 288 289 290 291 /** 292 * Sets the seed of this generator (which is also the current state). 293 * @param seed the seed to use for this LightRNG, as if it was constructed with this seed. 294 */ 295 public void setSeed( final long seed ) { 296 state = seed; 297 } 298 /** 299 * Sets the seed (also the current state) of this generator. 300 * @param seed the seed to use for this LightRNG, as if it was constructed with this seed. 301 */ 302 @Override 303 public void setState( final long seed ) { 304 state = seed; 305 } 306 /** 307 * Gets the current state of this generator. 308 * @return the current seed of this LightRNG, changed once per call to nextLong() 309 */ 310 @Override 311 public long getState() { 312 return state; 313 } 314 315 /** 316 * Advances or rolls back the LightRNG's state without actually generating each number. Skips forward 317 * or backward a number of steps specified by advance, where a step is equal to one call to nextLong(), 318 * and returns the random number produced at that step (you can get the state with {@link #getState()}). 319 * 320 * @param advance Number of future generations to skip over; can be negative to backtrack, 0 gets the most recent generated number 321 * @return the random long generated after skipping advance numbers 322 */ 323 @Override 324 public long skip(long advance) { 325 long z = (state += 0x9E3779B97F4A7C15L * advance); 326 z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L; 327 z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL; 328 return z ^ (z >>> 31); 329 } 330 331 332 @Override 333 public String toString() { 334 return "LightRNG with state 0x" + StringKit.hex(state) + 'L'; 335 } 336 337 @Override 338 public boolean equals(Object o) { 339 if (this == o) return true; 340 if (o == null || getClass() != o.getClass()) return false; 341 342 LightRNG lightRNG = (LightRNG) o; 343 344 return state == lightRNG.state; 345 } 346 347 @Override 348 public int hashCode() { 349 return (int) (state ^ (state >>> 32)); 350 } 351 352 public static long determine(long state) 353 { 354 return ((state = ((state = ((state *= 0x9E3779B97F4A7C15L) ^ state >>> 30) * 0xBF58476D1CE4E5B9L) ^ state >>> 27) * 0x94D049BB133111EBL) ^ state >>> 31); 355 } 356 public static long determine(final int a, final int b) 357 { 358 long state = 0x9E3779B97F4A7C15L + (a & 0xFFFFFFFFL) + ((long)b << 32); 359 state = ((state >>> 30) ^ state) * 0xBF58476D1CE4E5B9L; 360 state = (state ^ (state >>> 27)) * 0x94D049BB133111EBL; 361 return state ^ (state >>> 31); 362 } 363 364 public static int determineBounded(long state, final int bound) 365 { 366 return (int)((bound * (((state = ((state = ((state *= 0x9E3779B97F4A7C15L) ^ state >>> 30) * 0xBF58476D1CE4E5B9L) ^ state >>> 27) * 0x94D049BB133111EBL) ^ state >>> 31) & 0x7FFFFFFFL)) >> 31); 367 } 368 369 /** 370 * Returns a random float that is deterministic based on state; if state is the same on two calls to this, this will 371 * return the same float. This is expected to be called with a changing variable, e.g. {@code determine(++state)}, 372 * where the increment for state should be odd but otherwise doesn't really matter. This multiplies state by 373 * {@code 0x9E3779B97F4A7C15L} within this method, so using a small increment won't be much different from using a 374 * very large one, as long as it is odd. The period is 2 to the 64 if you increment or decrement by 1, but there are 375 * only 2 to the 30 possible floats between 0 and 1. 376 * @param state a variable that should be different every time you want a different random result; 377 * using {@code determine(++state)} is recommended to go forwards or {@code determine(--state)} to 378 * generate numbers in reverse order 379 * @return a pseudo-random float between 0f (inclusive) and 1f (exclusive), determined by {@code state} 380 */ 381 public static float determineFloat(long state) { return (((state = ((state = ((state *= 0x9E3779B97F4A7C15L) ^ state >>> 30) * 0xBF58476D1CE4E5B9L) ^ state >>> 27) * 0x94D049BB133111EBL) ^ state >>> 31) & 0xFFFFFF) * 0x1p-24f; } 382 383 /** 384 * Returns a random double that is deterministic based on state; if state is the same on two calls to this, this 385 * will return the same float. This is expected to be called with a changing variable, e.g. 386 * {@code determine(++state)}, where the increment for state should be odd but otherwise doesn't really matter. This 387 * multiplies state by {@code 0x9E3779B97F4A7C15L} within this method, so using a small increment won't be much 388 * different from using a very large one, as long as it is odd. The period is 2 to the 64 if you increment or 389 * decrement by 1, but there are only 2 to the 62 possible doubles between 0 and 1. 390 * @param state a variable that should be different every time you want a different random result; 391 * using {@code determine(++state)} is recommended to go forwards or {@code determine(--state)} to 392 * generate numbers in reverse order 393 * @return a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive), determined by {@code state} 394 */ 395 public static double determineDouble(long state) { return (((state = ((state = ((state *= 0x9E3779B97F4A7C15L) ^ state >>> 30) * 0xBF58476D1CE4E5B9L) ^ state >>> 27) * 0x94D049BB133111EBL) ^ state >>> 31) & 0x1FFFFFFFFFFFFFL) * 0x1p-53; } 396}