JenkinsSmallFast64.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.source64;

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

  19. /**
  20.  * Implement Bob Jenkins's small fast (JSF) 64-bit generator.
  21.  *
  22.  * <p>The state size is 256-bits.</p>
  23.  *
  24.  * @see <a href="https://burtleburtle.net/bob/rand/smallprng.html">A small noncryptographic PRNG</a>
  25.  * @since 1.3
  26.  */
  27. public class JenkinsSmallFast64 extends LongProvider {
  28.     /** State a. */
  29.     private long a;
  30.     /** State b. */
  31.     private long b;
  32.     /** State c. */
  33.     private long c;
  34.     /** Statd d. */
  35.     private long d;

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

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

  56.     /** {@inheritDoc} */
  57.     @Override
  58.     public final long next() {
  59.         final long e = a - Long.rotateLeft(b, 7);
  60.         a = b ^ Long.rotateLeft(c, 13);
  61.         b = c + Long.rotateLeft(d, 37);
  62.         c = d + e;
  63.         d = e + a;
  64.         return d;
  65.     }

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

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

  76.         final long[] tmp = NumberFactory.makeLongArray(parts[0]);
  77.         a = tmp[0];
  78.         b = tmp[1];
  79.         c = tmp[2];
  80.         d = tmp[3];

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