src/java.base/share/classes/java/util/random/MRG32k3a.java
branchJDK-8193209-branch
changeset 57547 56cbdc3ea079
parent 57437 f02ffcb61dce
equal deleted inserted replaced
57546:1ca1cfdcb451 57547:56cbdc3ea079
    25 
    25 
    26 package java.util.random;
    26 package java.util.random;
    27 
    27 
    28 import java.math.BigInteger;
    28 import java.math.BigInteger;
    29 import java.util.concurrent.atomic.AtomicLong;
    29 import java.util.concurrent.atomic.AtomicLong;
       
    30 import java.util.random.RandomGenerator.LeapableGenerator;
       
    31 import java.util.random.RandomSupport.AbstractArbitrarilyJumpableGenerator;
    30 
    32 
    31 /**
    33 /**
    32  * A generator of uniform pseudorandom values applicable for use in
    34  * A generator of uniform pseudorandom values applicable for use in
    33  * (among other contexts) isolated parallel computations that may
    35  * (among other contexts) isolated parallel computations that may
    34  * generate subtasks.  Class {@link MRG32k3a} implements
    36  * generate subtasks.  Class {@link MRG32k3a} implements
    35  * interfaces {@link RandomNumberGenerator} and {@link AbstractArbitrarilyJumpableRNG},
    37  * interfaces {@link RandomGenerator} and {@link AbstractArbitrarilyJumpableGenerator},
    36  * and therefore supports methods for producing pseudorandomly chosen
    38  * and therefore supports methods for producing pseudorandomly chosen
    37  * numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
    39  * numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
    38  * as well as creating new {@link Xoroshiro128PlusMRG32k3a} objects
    40  * as well as creating new {@link Xoroshiro128PlusMRG32k3a} objects
    39  * by "jumping" or "leaping".
    41  * by "jumping" or "leaping".
    40  * <p>
    42  * <p>
    51  * seed unless the {@linkplain System#getProperty system property}
    53  * seed unless the {@linkplain System#getProperty system property}
    52  * {@code java.util.secureRandomSeed} is set to {@code true}.
    54  * {@code java.util.secureRandomSeed} is set to {@code true}.
    53  *
    55  *
    54  * @since 14
    56  * @since 14
    55  */
    57  */
    56 public final class MRG32k3a extends AbstractArbitrarilyJumpableRNG {
    58 public final class MRG32k3a extends AbstractArbitrarilyJumpableGenerator {
    57 
    59 
    58     /*
    60     /*
    59      * Implementation Overview.
    61      * Implementation Overview.
    60      *
    62      *
    61      * See http://simul.iro.umontreal.ca/rng/MRG32k3a.c .
    63      * See http://simul.iro.umontreal.ca/rng/MRG32k3a.c .
    85 
    87 
    86     /**
    88     /**
    87      * The seed generator for default constructors.
    89      * The seed generator for default constructors.
    88      */
    90      */
    89     private static final AtomicLong DEFAULT_GEN =
    91     private static final AtomicLong DEFAULT_GEN =
    90         new AtomicLong(RNGSupport.initialSeed());
    92         new AtomicLong(RandomSupport.initialSeed());
    91 
    93 
    92     /*
    94     /*
    93       32-bits Random number generator U(0,1): MRG32k3a
    95       32-bits Random number generator U(0,1): MRG32k3a
    94       Author: Pierre L'Ecuyer,
    96       Author: Pierre L'Ecuyer,
    95       Source: Good Parameter Sets for Combined Multiple Recursive Random
    97       Source: Good Parameter Sets for Combined Multiple Recursive Random
   130                      u + m + ((M1_DEFICIT + 1) >>> 1) - (r = u % n) < 0;
   132                      u + m + ((M1_DEFICIT + 1) >>> 1) - (r = u % n) < 0;
   131                      u = (int)nextDouble() >>> 1)
   133                      u = (int)nextDouble() >>> 1)
   132                     ;
   134                     ;
   133                 return (r + origin);
   135                 return (r + origin);
   134             } else {
   136             } else {
   135                 return RNGSupport.boundedNextInt(this, origin, bound);
   137                 return RandomSupport.boundedNextInt(this, origin, bound);
   136             }
   138             }
   137         } else {
   139         } else {
   138             return nextInt();
   140             return nextInt();
   139         }
   141         }
   140     }
   142     }
   217      * generate sequences of values that are statistically independent
   219      * generate sequences of values that are statistically independent
   218      * of those of any other instances in the current program; and
   220      * of those of any other instances in the current program; and
   219      * may, and typically does, vary across program invocations.
   221      * may, and typically does, vary across program invocations.
   220      */
   222      */
   221     public MRG32k3a() {
   223     public MRG32k3a() {
   222         this(DEFAULT_GEN.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
   224         this(DEFAULT_GEN.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
   223     }
   225     }
   224 
   226 
   225     /**
   227     /**
   226      * Creates a new instance of {@link Xoshiro256StarStar} using the specified array of
   228      * Creates a new instance of {@link Xoshiro256StarStar} using the specified array of
   227      * initial seed bytes. Instances of {@link Xoshiro256StarStar} created with the same
   229      * initial seed bytes. Instances of {@link Xoshiro256StarStar} created with the same
   229      *
   231      *
   230      * @param seed the initial seed
   232      * @param seed the initial seed
   231      */
   233      */
   232     public MRG32k3a(byte[] seed) {
   234     public MRG32k3a(byte[] seed) {
   233         // Convert the seed to 6 int values.
   235         // Convert the seed to 6 int values.
   234         int[] data = RNGSupport.convertSeedBytesToInts(seed, 6, 0);
   236         int[] data = RandomSupport.convertSeedBytesToInts(seed, 6, 0);
   235         int s10 = data[0], s11 = data[1], s12 = data[2];
   237         int s10 = data[0], s11 = data[1], s12 = data[2];
   236         int s20 = data[3], s21 = data[4], s22 = data[5];
   238         int s20 = data[3], s21 = data[4], s22 = data[5];
   237         this.s10 = ((double)(((long)s10) & 0x00000000ffffffffL)) % M1;
   239         this.s10 = ((double)(((long)s10) & 0x00000000ffffffffL)) % M1;
   238         this.s11 = ((double)(((long)s11) & 0x00000000ffffffffL)) % M1;
   240         this.s11 = ((double)(((long)s11) & 0x00000000ffffffffL)) % M1;
   239         this.s12 = ((double)(((long)s12) & 0x00000000ffffffffL)) % M1;
   241         this.s12 = ((double)(((long)s12) & 0x00000000ffffffffL)) % M1;