IntRandomGenerator.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * This is not the original file distributed by the Apache Software Foundation
- * It has been modified by the Hipparchus project
- */
- package org.hipparchus.random;
- import org.hipparchus.exception.LocalizedCoreFormats;
- import org.hipparchus.exception.MathIllegalArgumentException;
- /**
- * Base class for all {@code int}-based (32-bit) random generator
- * implementations.
- */
- abstract class IntRandomGenerator extends BaseRandomGenerator {
- /** {@inheritDoc} */
- @Override
- public abstract int nextInt();
- /** {@inheritDoc} */
- @Override
- public boolean nextBoolean() {
- return (nextInt() >>> 31) != 0;
- }
- /** {@inheritDoc} */
- @Override
- public double nextDouble() {
- final long high = ((long) (nextInt() >>> 6)) << 26;
- final int low = nextInt() >>> 6;
- return (high | low) * 0x1.0p-52d;
- }
- /** {@inheritDoc} */
- @Override
- public float nextFloat() {
- return (nextInt() >>> 9) * 0x1.0p-23f;
- }
- /** {@inheritDoc} */
- @Override
- public long nextLong() {
- return (((long) nextInt()) << 32) | (nextInt() & 0xffffffffL);
- }
- /** {@inheritDoc} */
- @Override
- public void nextBytes(byte[] bytes) {
- nextBytesFill(bytes, 0, bytes.length);
- }
- /** {@inheritDoc} */
- @Override
- public void nextBytes(byte[] bytes, int start, int len) {
- if (start < 0 ||
- start >= bytes.length) {
- throw new MathIllegalArgumentException(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE,
- start, 0, bytes.length);
- }
- if (len < 0 ||
- len > bytes.length - start) {
- throw new MathIllegalArgumentException(LocalizedCoreFormats.OUT_OF_RANGE_SIMPLE,
- len, 0, bytes.length - start);
- }
- nextBytesFill(bytes, start, len);
- }
- /**
- * Generates random bytes and places them into a user-supplied array.
- *
- * @see #nextBytes(byte[], int, int)
- *
- * @param bytes the non-null byte array in which to put the random bytes
- * @param offset the starting index for inserting the generated bytes into
- * the array
- * @param len the number of bytes to generate
- * @throws MathIllegalArgumentException if {@code offset < 0} or
- * {@code offset + len >= bytes.length}
- */
- private void nextBytesFill(byte[] bytes, int offset, int len) {
- int index = offset; // Index of first insertion.
- // Index of first insertion plus multiple of 4 part of length
- // (i.e. length with 2 least significant bits unset).
- final int indexLoopLimit = index + (len & 0x7ffffffc);
- // Start filling in the byte array, 4 bytes at a time.
- while (index < indexLoopLimit) {
- final int random = nextInt();
- bytes[index++] = (byte) random;
- bytes[index++] = (byte) (random >>> 8);
- bytes[index++] = (byte) (random >>> 16);
- bytes[index++] = (byte) (random >>> 24);
- }
- final int indexLimit = offset + len; // Index of last insertion + 1.
- // Fill in the remaining bytes.
- if (index < indexLimit) {
- int random = nextInt();
- while (true) {
- bytes[index++] = (byte) random;
- if (index < indexLimit) {
- random >>>= 8;
- } else {
- break;
- }
- }
- }
- }
- }