JenkinsSmallFast32.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.rng.core.source32;

  18. import org.apache.commons.rng.core.util.NumberFactory;

  19. /**
  20.  * Implement Bob Jenkins's small fast (JSF) 32-bit generator.
  21.  *
  22.  * <p>The state size is 128-bits; the shortest period is expected to be about 2<sup>94</sup>
  23.  * and it expected that about one seed will run into another seed within 2<sup>64</sup> values.</p>
  24.  *
  25.  * @see <a href="https://burtleburtle.net/bob/rand/smallprng.html">A small noncryptographic PRNG</a>
  26.  * @since 1.3
  27.  */
  28. public class JenkinsSmallFast32 extends IntProvider {
  29.     /** State a. */
  30.     private int a;
  31.     /** State b. */
  32.     private int b;
  33.     /** State c. */
  34.     private int c;
  35.     /** Statd d. */
  36.     private int d;

  37.     /**
  38.      * Creates an instance with the given seed.
  39.      *
  40.      * @param seed Initial seed.
  41.      */
  42.     public JenkinsSmallFast32(Integer seed) {
  43.         setSeedInternal(seed);
  44.     }

  45.     /**
  46.      * Seeds the RNG.
  47.      *
  48.      * @param seed Seed.
  49.      */
  50.     private void setSeedInternal(int seed) {
  51.         a = 0xf1ea5eed;
  52.         b = c = d = seed;
  53.         for (int i = 0; i < 20; i++) {
  54.             next();
  55.         }
  56.     }

  57.     /** {@inheritDoc} */
  58.     @Override
  59.     public final int next() {
  60.         final int e = a - Integer.rotateLeft(b, 27);
  61.         a = b ^ Integer.rotateLeft(c, 17);
  62.         b = c + d;
  63.         c = d + e;
  64.         d = e + a;
  65.         return d;
  66.     }

  67.     /** {@inheritDoc} */
  68.     @Override
  69.     protected byte[] getStateInternal() {
  70.         return composeStateInternal(NumberFactory.makeByteArray(new int[] {a, b, c, d}),
  71.                                     super.getStateInternal());
  72.     }

  73.     /** {@inheritDoc} */
  74.     @Override
  75.     protected void setStateInternal(byte[] s) {
  76.         final byte[][] parts = splitStateInternal(s, 4 * 4);

  77.         final int[] tmp = NumberFactory.makeIntArray(parts[0]);
  78.         a = tmp[0];
  79.         b = tmp[1];
  80.         c = tmp[2];
  81.         d = tmp[3];

  82.         super.setStateInternal(parts[1]);
  83.     }
  84. }