View Javadoc
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  
19  import org.apache.commons.rng.core.util.NumberFactory;
20  
21  /**
22   * Implement Bob Jenkins's small fast (JSF) 64-bit generator.
23   *
24   * <p>The state size is 256-bits.</p>
25   *
26   * @see <a href="https://burtleburtle.net/bob/rand/smallprng.html">A small noncryptographic PRNG</a>
27   * @since 1.3
28   */
29  public class JenkinsSmallFast64 extends LongProvider {
30      /** State a. */
31      private long a;
32      /** State b. */
33      private long b;
34      /** State c. */
35      private long c;
36      /** Statd d. */
37      private long d;
38  
39      /**
40       * Creates an instance with the given seed.
41       *
42       * @param seed Initial seed.
43       */
44      public JenkinsSmallFast64(Long seed) {
45          setSeedInternal(seed);
46      }
47  
48      /**
49       * Seeds the RNG.
50       *
51       * @param seed Seed.
52       */
53      private void setSeedInternal(long seed) {
54          a = 0xf1ea5eedL;
55          b = c = d = seed;
56          for (int i = 0; i < 20; i++) {
57              next();
58          }
59      }
60  
61      /** {@inheritDoc} */
62      @Override
63      public final long next() {
64          final long e = a - Long.rotateLeft(b, 7);
65          a = b ^ Long.rotateLeft(c, 13);
66          b = c + Long.rotateLeft(d, 37);
67          c = d + e;
68          d = e + a;
69          return d;
70      }
71  
72      /** {@inheritDoc} */
73      @Override
74      protected byte[] getStateInternal() {
75          return composeStateInternal(NumberFactory.makeByteArray(new long[] {a, b, c, d}),
76                                      super.getStateInternal());
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      protected void setStateInternal(byte[] s) {
82          final byte[][] parts = splitStateInternal(s, 4 * 8);
83  
84          final long[] tmp = NumberFactory.makeLongArray(parts[0]);
85          a = tmp[0];
86          b = tmp[1];
87          c = tmp[2];
88          d = tmp[3];
89  
90          super.setStateInternal(parts[1]);
91      }
92  }