1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.rng.core.source32;
19
20 import org.apache.commons.rng.core.util.NumberFactory;
21 import org.apache.commons.rng.core.BaseProvider;
22
23
24
25
26
27 public abstract class IntProvider
28 extends BaseProvider
29 implements RandomIntSource {
30
31
32
33
34
35
36 private int booleanSource;
37
38
39
40
41
42
43
44
45
46
47 private int booleanBitMask;
48
49
50 @Override
51 protected byte[] getStateInternal() {
52 final int[] state = new int[] { booleanSource,
53 booleanBitMask };
54 return composeStateInternal(super.getStateInternal(),
55 NumberFactory.makeByteArray(state));
56 }
57
58
59 @Override
60 protected void setStateInternal(byte[] s) {
61 final byte[][] c = splitStateInternal(s, 8);
62 final int[] state = NumberFactory.makeIntArray(c[0]);
63 booleanSource = state[0];
64 booleanBitMask = state[1];
65 super.setStateInternal(c[1]);
66 }
67
68
69 @Override
70 public int nextInt() {
71 return next();
72 }
73
74
75 @Override
76 public boolean nextBoolean() {
77
78 booleanBitMask <<= 1;
79
80 if (booleanBitMask == 0) {
81
82 booleanBitMask = 1;
83
84 booleanSource = nextInt();
85 }
86
87 return (booleanSource & booleanBitMask) != 0;
88 }
89
90
91 @Override
92 public double nextDouble() {
93 return NumberFactory.makeDouble(nextInt(), nextInt());
94 }
95
96
97 @Override
98 public float nextFloat() {
99 return NumberFactory.makeFloat(nextInt());
100 }
101
102
103 @Override
104 public long nextLong() {
105 return NumberFactory.makeLong(nextInt(), nextInt());
106 }
107
108
109 @Override
110 public void nextBytes(byte[] bytes) {
111 nextBytesFill(this, bytes, 0, bytes.length);
112 }
113
114
115 @Override
116 public void nextBytes(byte[] bytes,
117 int start,
118 int len) {
119 checkIndex(0, bytes.length - 1, start);
120 checkIndex(0, bytes.length - start, len);
121
122 nextBytesFill(this, bytes, start, len);
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 static void nextBytesFill(RandomIntSource source,
140 byte[] bytes,
141 int start,
142 int len) {
143 int index = start;
144
145
146
147 final int indexLoopLimit = index + (len & 0x7ffffffc);
148
149
150 while (index < indexLoopLimit) {
151 final int random = source.next();
152 bytes[index++] = (byte) random;
153 bytes[index++] = (byte) (random >>> 8);
154 bytes[index++] = (byte) (random >>> 16);
155 bytes[index++] = (byte) (random >>> 24);
156 }
157
158 final int indexLimit = start + len;
159
160
161 if (index < indexLimit) {
162 int random = source.next();
163 while (true) {
164 bytes[index++] = (byte) random;
165 if (index < indexLimit) {
166 random >>>= 8;
167 } else {
168 break;
169 }
170 }
171 }
172 }
173 }