001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.rng.core.source64; 019 020import org.apache.commons.rng.core.util.NumberFactory; 021import org.apache.commons.rng.core.BaseProvider; 022 023/** 024 * Base class for all implementations that provide a {@code long}-based 025 * source randomness. 026 */ 027public abstract class LongProvider 028 extends BaseProvider 029 implements RandomLongSource { 030 031 /** Empty boolean source. This is the location of the sign-bit after 63 right shifts on 032 * the boolean source. */ 033 private static final long EMPTY_BOOL_SOURCE = 1; 034 /** Empty int source. This requires a negative value as the sign-bit is used to 035 * trigger a refill. */ 036 private static final long EMPTY_INT_SOURCE = -1; 037 038 /** 039 * Provides a bit source for booleans. 040 * 041 * <p>A cached value from a call to {@link #next()}. 042 * 043 * <p>Only stores 63-bits when full as 1 bit has already been consumed. 044 * The sign bit is a flag that shifts down so the source eventually equals 1 045 * when all bits are consumed and will trigger a refill. 046 */ 047 private long booleanSource = EMPTY_BOOL_SOURCE; 048 049 /** 050 * Provides a source for ints. 051 * 052 * <p>A cached half-value value from a call to {@link #next()}. 053 * The int is stored in the lower 32 bits with zeros in the upper bits. 054 * When empty this is set to negative to trigger a refill. 055 */ 056 private long intSource = EMPTY_INT_SOURCE; 057 058 /** 059 * Creates a new instance. 060 */ 061 public LongProvider() { 062 super(); 063 } 064 065 /** 066 * Creates a new instance copying the state from the source. 067 * 068 * <p>This provides base functionality to allow a generator to create a copy, for example 069 * for use in the {@link org.apache.commons.rng.JumpableUniformRandomProvider 070 * JumpableUniformRandomProvider} interface. 071 * 072 * @param source Source to copy. 073 * @since 1.3 074 */ 075 protected LongProvider(LongProvider source) { 076 booleanSource = source.booleanSource; 077 intSource = source.intSource; 078 } 079 080 /** 081 * Reset the cached state used in the default implementation of {@link #nextBoolean()} 082 * and {@link #nextInt()}. 083 * 084 * <p>This should be used when the state is no longer valid, for example after a jump 085 * performed for the {@link org.apache.commons.rng.JumpableUniformRandomProvider 086 * JumpableUniformRandomProvider} interface.</p> 087 * 088 * @since 1.3 089 */ 090 protected void resetCachedState() { 091 booleanSource = EMPTY_BOOL_SOURCE; 092 intSource = EMPTY_INT_SOURCE; 093 } 094 095 /** {@inheritDoc} */ 096 @Override 097 protected byte[] getStateInternal() { 098 final long[] state = {booleanSource, intSource}; 099 return composeStateInternal(NumberFactory.makeByteArray(state), 100 super.getStateInternal()); 101 } 102 103 /** {@inheritDoc} */ 104 @Override 105 protected void setStateInternal(byte[] s) { 106 final byte[][] c = splitStateInternal(s, 2 * Long.BYTES); 107 final long[] state = NumberFactory.makeLongArray(c[0]); 108 booleanSource = state[0]; 109 intSource = state[1]; 110 super.setStateInternal(c[1]); 111 } 112 113 /** {@inheritDoc} */ 114 @Override 115 public long nextLong() { 116 return next(); 117 } 118 119 /** {@inheritDoc} */ 120 @Override 121 public int nextInt() { 122 long bits = intSource; 123 if (bits < 0) { 124 // Refill 125 bits = next(); 126 // Store high 32 bits, return low 32 bits 127 intSource = bits >>> 32; 128 return (int) bits; 129 } 130 // Reset and return previous low bits 131 intSource = -1; 132 return (int) bits; 133 } 134 135 /** {@inheritDoc} */ 136 @Override 137 public boolean nextBoolean() { 138 long bits = booleanSource; 139 if (bits == 1) { 140 // Refill 141 bits = next(); 142 // Store a refill flag in the sign bit and the unused 63 bits, return lowest bit 143 booleanSource = Long.MIN_VALUE | (bits >>> 1); 144 return (bits & 0x1) == 1; 145 } 146 // Shift down eventually triggering refill, return current lowest bit 147 booleanSource = bits >>> 1; 148 return (bits & 0x1) == 1; 149 } 150}