001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 package org.apache.commons.lang.math; 020 021 import java.util.Random; 022 023 /** 024 * <p><code>JVMRandom</code> is a wrapper that supports all possible 025 * Random methods via the {@link java.lang.Math#random()} method 026 * and its system-wide {@link Random} object.</p> 027 * <p> 028 * It does this to allow for a Random class in which the seed is 029 * shared between all members of the class - a better name would 030 * have been SharedSeedRandom. 031 * <p> 032 * <b>N.B.</b> the current implementation overrides the methods 033 * {@link Random#nextInt(int)} and {@link Random#nextLong()} 034 * to produce positive numbers ranging from 0 (inclusive) 035 * to MAX_VALUE (exclusive). 036 * 037 * @since 2.0 038 * @version $Id: JVMRandom.java 911986 2010-02-19 21:19:05Z niallp $ 039 */ 040 public final class JVMRandom extends Random { 041 042 /** 043 * Required for serialization support. 044 * 045 * @see java.io.Serializable 046 */ 047 private static final long serialVersionUID = 1L; 048 049 private static final Random SHARED_RANDOM = new Random(); 050 051 /** 052 * Ensures that only the parent constructor can call reseed. 053 */ 054 private boolean constructed = false; 055 056 /** 057 * Constructs a new instance. 058 */ 059 public JVMRandom() { 060 this.constructed = true; 061 } 062 063 /** 064 * Unsupported in 2.0. 065 * 066 * @param seed ignored 067 * @throws UnsupportedOperationException 068 */ 069 public synchronized void setSeed(long seed) { 070 if (this.constructed) { 071 throw new UnsupportedOperationException(); 072 } 073 } 074 075 /** 076 * Unsupported in 2.0. 077 * 078 * @return Nothing, this method always throws an UnsupportedOperationException. 079 * @throws UnsupportedOperationException 080 */ 081 public synchronized double nextGaussian() { 082 throw new UnsupportedOperationException(); 083 } 084 085 /** 086 * Unsupported in 2.0. 087 * 088 * @param byteArray ignored 089 * @throws UnsupportedOperationException 090 */ 091 public void nextBytes(byte[] byteArray) { 092 throw new UnsupportedOperationException(); 093 } 094 095 /** 096 * <p>Returns the next pseudorandom, uniformly distributed int value 097 * from the Math.random() sequence.</p> 098 * Identical to <code>nextInt(Integer.MAX_VALUE)</code> 099 * <p> 100 * <b>N.B. All values are >= 0.<b> 101 * </p> 102 * @return the random int 103 */ 104 public int nextInt() { 105 return nextInt(Integer.MAX_VALUE); 106 } 107 108 /** 109 * <p>Returns a pseudorandom, uniformly distributed int value between 110 * <code>0</code> (inclusive) and the specified value (exclusive), from 111 * the Math.random() sequence.</p> 112 * 113 * @param n the specified exclusive max-value 114 * @return the random int 115 * @throws IllegalArgumentException when <code>n <= 0</code> 116 */ 117 public int nextInt(int n) { 118 return SHARED_RANDOM.nextInt(n); 119 } 120 121 /** 122 * <p>Returns the next pseudorandom, uniformly distributed long value 123 * from the Math.random() sequence.</p> 124 * Identical to <code>nextLong(Long.MAX_VALUE)</code> 125 * <p> 126 * <b>N.B. All values are >= 0.<b> 127 * </p> 128 * @return the random long 129 */ 130 public long nextLong() { 131 return nextLong(Long.MAX_VALUE); 132 } 133 134 135 /** 136 * <p>Returns a pseudorandom, uniformly distributed long value between 137 * <code>0</code> (inclusive) and the specified value (exclusive), from 138 * the Math.random() sequence.</p> 139 * 140 * @param n the specified exclusive max-value 141 * @return the random long 142 * @throws IllegalArgumentException when <code>n <= 0</code> 143 */ 144 public static long nextLong(long n) { 145 if (n <= 0) { 146 throw new IllegalArgumentException( 147 "Upper bound for nextInt must be positive" 148 ); 149 } 150 // Code adapted from Harmony Random#nextInt(int) 151 if ((n & -n) == n) { // n is power of 2 152 // dropping lower order bits improves behaviour for low values of n 153 return next63bits() >> 63 // drop all the bits 154 - bitsRequired(n-1); // except the ones we need 155 } 156 // Not a power of two 157 long val; 158 long bits; 159 do { // reject some values to improve distribution 160 bits = next63bits(); 161 val = bits % n; 162 } while (bits - val + (n - 1) < 0); 163 return val; 164 } 165 166 /** 167 * <p>Returns the next pseudorandom, uniformly distributed boolean value 168 * from the Math.random() sequence.</p> 169 * 170 * @return the random boolean 171 */ 172 public boolean nextBoolean() { 173 return SHARED_RANDOM.nextBoolean(); 174 } 175 176 /** 177 * <p>Returns the next pseudorandom, uniformly distributed float value 178 * between <code>0.0</code> and <code>1.0</code> from the Math.random() 179 * sequence.</p> 180 * 181 * @return the random float 182 */ 183 public float nextFloat() { 184 return SHARED_RANDOM.nextFloat(); 185 } 186 187 /** 188 * <p>Synonymous to the Math.random() call.</p> 189 * 190 * @return the random double 191 */ 192 public double nextDouble() { 193 return SHARED_RANDOM.nextDouble(); 194 } 195 196 /** 197 * Get the next unsigned random long 198 * @return unsigned random long 199 */ 200 private static long next63bits(){ 201 // drop the sign bit to leave 63 random bits 202 return SHARED_RANDOM.nextLong() & 0x7fffffffffffffffL; 203 } 204 205 /** 206 * Count the number of bits required to represent a long number. 207 * 208 * @param num long number 209 * @return number of bits required 210 */ 211 private static int bitsRequired(long num){ 212 // Derived from Hacker's Delight, Figure 5-9 213 long y=num; // for checking right bits 214 int n=0; // number of leading zeros found 215 while(true){ 216 // 64 = number of bits in a long 217 if (num < 0) { 218 return 64-n; // no leading zeroes left 219 } 220 if (y == 0) { 221 return n; // no bits left to check 222 } 223 n++; 224 num=num << 1; // check leading bits 225 y=y >> 1; // check trailing bits 226 } 227 } 228 }