Java:0 <= x <n范围内的随机长整数
随机类有一个方法来在给定的范围内产生随机的int。 例如:
Random r = new Random(); int x = r.nextInt(100);
这将产生一个大于或等于0且小于100的整数。我想用长号完全相同。
long y = magicRandomLongGenerator(100);
随机类只有nextLong(),但不允许设置范围。
ThreadLocalRandom.current().nextLong(n)
(对于0≤x<n)和ThreadLocalRandom.current().nextLong(m, n)
(对于m≤x<n)。 有关详细信息,请参阅@Alex的答案。
如果你使用Java 6 (或者Android 4.x),你需要使用一个外部库(例如org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1)
mawaldne的答案),或者实现你自己的nextLong(n)
。
根据http://java.sun.com/j2se/1.5.0/docs/api/java/util/Random.html,nextInt被实现为;
public int nextInt(int n) { if (n<=0) throw new IllegalArgumentException("n must be positive"); if ((n & -n) == n) // ie, n is a power of 2 return (int)((n * (long)next(31)) >> 31); int bits, val; do { bits = next(31); val = bits % n; } while(bits - val + (n-1) < 0); return val; }
所以我们可以修改这个来执行nextLong
:
long nextLong(Random rng, long n) { // error checking and 2^x checking removed for simplicity. long bits, val; do { bits = (rng.nextLong() << 1) >>> 1; val = bits % n; } while (bits-val+(n-1) < 0L); return val; }
在一个范围内生成一个数字(没有实用方法)的标准方法是只使用范围为:
long range = 1234567L; Random r = new Random() long number = (long)(r.nextDouble()*range);
会给你一个介于0(含)和range(含)之间的长时间。 同样,如果你想要一个x和y之间的数字:
long x = 1234567L; long y = 23456789L; Random r = new Random() long number = x+((long)(r.nextDouble()*(yx)));
会给你从1234567(含)到123456789(不含)
注意:检查括号,因为铸造长期比乘法有更高的优先级。
ThreadLocalRandom
ThreadLocalRandom
有一个nextLong(long bound)
方法。
long v = ThreadLocalRandom.current().nextLong(100);
如果你需要一个不是0的nextLong(long origin, long bound)
它也有nextLong(long origin, long bound)
传递原点(包含)和绑定(exclusive)。
long v = ThreadLocalRandom.current().nextLong(10,100); // For 2-digit integers, 10-99 inclusive.
SplittableRandom
具有相同的nextLong
方法,并允许您select一个种子,如果你想要一个可重复的数字序列。
上面的方法工作很好。 如果您使用的是Apache Commons(org.apache.commons.math.random),请查看RandomData。 它有一个方法:nextLong(长下,长上)
使用'%'运算符
resultingNumber = (r.nextLong() % (maximum - minimum)) + minimum;
通过使用'%'运算符,我们将剩余部分除以最大值。 这使我们只有从0(包括)到除数(不包括)的数字。
例如:
public long randLong(long min, long max) { return (new java.util.Random().nextLong() % (max - min)) + min; }
非常感谢你的这篇文章。 这正是我所需要的。 必须改变一些东西来获得我曾经工作的部分。
我有以下(包括上面):
long number = x+((long)r.nextDouble()*(yx));
通过将其更改为:
long number = x+ (long)(r.nextDouble()*(yx));
因为(long)r.nextDouble()
总是为零。
从随机页面:
nextLong方法是通过类Random来实现的,就像通过:
public long nextLong() { return ((long)next(32) << 32) + next(32); }
由于Random类只使用48位的种子,因此该algorithm不会返回所有可能的长整型值。
所以如果你想获得一个Long
,你已经不能获得完整的64位范围。
我build议,如果你的射程接近2的幂,那么就像在这个片段中构buildLong
一样:
next(32) + ((long)nextInt(8) << 3)
例如获得一个35位的范围。
进一步改进kennytm的答案:考虑Java 8中实际实现的子类实现将是:
public class MyRandom extends Random { public long nextLong(long bound) { if (bound <= 0) { throw new IllegalArgumentException("bound must be positive"); } long r = nextLong() & Long.MAX_VALUE; long m = bound - 1L; if ((bound & m) == 0) { // ie, bound is a power of 2 r = (bound * r) >> (Long.SIZE - 1); } else { for (long u = r; u - (r = u % bound) + m < 0L; u = nextLong() & Long.MAX_VALUE); } return r; } }
这个怎么样:
public static long nextLong(@NonNull Random r, long min, long max) { if (min > max) throw new IllegalArgumentException("min>max"); if (min == max) return min; long n = r.nextLong(); //abs (use instead of Math.abs, which might return min value) : n = n == Long.MIN_VALUE ? 0 : n < 0 ? -n : n; //limit to range: n = n % (max - min); return min + n; }
?
使用r.nextDouble()
的方法应该使用:
long number = (long) (rand.nextDouble()*max); long number = x+(((long)r.nextDouble())*(yx));
public static long randomLong(long min, long max) { try { Random random = new Random(); long result = min + (long) (random.nextDouble() * (max - min)); return result; } catch (Throwable t) {t.printStackTrace();} return 0L; }
如果你想要一个在[0, m
)范围内长均匀分布的伪随机,可以尝试使用模运算符和绝对值方法结合nextLong()
方法,如下所示:
Math.abs(rand.nextLong()) % m;
rand
是你的Random对象。
模运算符将两个数字相除并输出这些数字的其余部分。 例如, 3 % 2
是1
因为3和2的余数是1。
由于nextLong()
生成一个长度在[ – (2 ^ 48),2 ^ 48)范围内的均匀分布的伪随机数,所以需要取其绝对值。 如果你不这样做, nextLong()
方法的模有50%的机会返回一个负值,超出了范围[0, m
)。
你最初要求的是在[0,100)范围内长均匀分布的伪随机。 下面的代码是这样的:
Math.abs(rand.nextLong()) % 100;
下面的方法将返回一个10000000000到9999999999之间的值
long MinimumNumber = 1000000000L long MaxiumNumber = 9999999999L public static long getRandomNumber(long MinimumNumber , long maxium){ Random random = new Random(); return random.nextLong() % (maxium - MinimumNumber) + maxium; }
//使用系统时间作为种子值来获得一个好的随机数
Random random = new Random(System.currentTimeMillis()); long x; do{ x=random.nextLong(); }while(x<0 && x > n);
//循环,直到获得大于或等于0且小于n的数字