Java:0中的随机长数< = x< n范围

时间:2010-03-30 14:41:21

标签: java random range long-integer

Random类有一个在给定范围内生成随机int的方法。例如:

Random r = new Random(); 
int x = r.nextInt(100);

这会产生一个大于等于0且小于100的int数。我想用长数做同样的事。

long y = magicRandomLongGenerator(100);

Random class只有nextLong(),但它不允许设置范围。

17 个答案:

答案 0 :(得分:135)

Java 7 (或Android API Level 21 = 5.0+)开始,您可以直接使用ThreadLocalRandom.current().nextLong(n)(对于0≤xThreadLocalRandom.current().nextLong(m, n)(对于m≤x@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)  // i.e., 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;
}

答案 1 :(得分:73)

在一个范围内生成数字(没有实用方法)的标准方法是只使用范围为的double:

long range = 1234567L;
Random r = new Random()
long number = (long)(r.nextDouble()*range);

会给你一个介于0(含)和范围(独家)之间的长。同样,如果你想要一个介于x和y之间的数字:

long x = 1234567L;
long y = 23456789L;
Random r = new Random()
long number = x+((long)(r.nextDouble()*(y-x)));

将从1234567(含)到123456789(独家)

给你很长的时间

注意:检查括号,因为施放到long的优先级高于乘法。

答案 2 :(得分:61)

ThreadLocalRandom

ThreadLocalRandom has a nextLong(long bound) method.

long v = ThreadLocalRandom.current().nextLong(100);

It also has nextLong(long origin, long bound) if you need an origin other than 0. Pass the origin (inclusive) and the bound (exclusive).

long v = ThreadLocalRandom.current().nextLong(10,100); // For 2-digit integers, 10-99 inclusive.

SplittableRandom has the same nextLong methods and allows you to choose a seed if you want a reproducible sequence of numbers.

答案 3 :(得分:12)

上述方法效果很好。如果您正在使用apache commons(org.apache.commons.math.random),请查看RandomData。它有一个方法:nextLong(长下,长上)

http://commons.apache.org/math/userguide/random.html

http://commons.apache.org/math/api-1.1/org/apache/commons/math/random/RandomData.html#nextLong(long,%20long)

答案 4 :(得分:11)

使用&#39;%&#39;操作

resultingNumber = (r.nextLong() % (maximum - minimum)) + minimum;

使用&#39;%&#39;运算符,我们将余数除以最大值。这使我们只有从0(包括)到除数(不包括)的数字。

例如:

public long randLong(long min, long max) {
    return (new java.util.Random().nextLong() % (max - min)) + min;
}

答案 5 :(得分:2)

非常感谢你这篇文章。这正是我所需要的。不得不改变一些东西来获得我以前工作的部分。

我得到了以下内容(包含在上面):

long number = x+((long)r.nextDouble()*(y-x));

通过将其更改为:

来工作
long number = x+ (long)(r.nextDouble()*(y-x));

因为(long)r.nextDouble()始终为零。

答案 6 :(得分:2)

如果你想要在[0,SELECT CustomerID, Name, GROUP_CONCAT(Order) AS Order FROM <table_name> GROUP BY CustomerID, Name )范围内长度均匀分布的伪随机数,请尝试使用模运算符和绝对值方法结合m方法,如下所示:

nextLong()

Math.abs(rand.nextLong()) % m; 是你的随机对象。

模运算符将两个数字分开并输出其余数字。例如,rand3 % 2,因为3和2的余数为1。

由于1在[ - (2 ^ 48),2 ^ 48)(或该范围内的某个地方)范围内生成均匀分布的伪随机数,因此您需要获取它的绝对值。如果你不这样做,nextLong()方法的模数有50%的几率返回一个负值,超出范围[0,nextLong())。

您最初请求的是均匀分布的伪随机数,范围为[0,100]。以下代码执行此操作:

m

答案 7 :(得分:1)

来自Random上的页面:

  

方法nextLong由Random类实现,如下所示:

public long nextLong() {
   return ((long)next(32) << 32) + next(32);
}
     

由于Random类使用的种子只有48位,因此该算法不会返回所有可能的长值。

因此,如果您想获得Long,那么您已经无法获得完整的64位范围。

我建议如果你的范围接近2的幂,那么就像在这个代码段中那样构建Long

next(32) + ((long)nextInt(8) << 3)
例如,

获得35位范围。

答案 8 :(得分:1)

进一步改进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) { // i.e., 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;
  }
}

答案 9 :(得分:1)

这个怎么样:

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;
}

答案 10 :(得分:1)

以下方法将返回介于10000000000到9999999999之间的值

long min = 1000000000L
long max = 9999999999L    

public static long getRandomNumber(long min, long max){

    Random random = new Random();         
    return random.nextLong() % (max - min) + max;

}

答案 11 :(得分:1)

通过 Java 8 API

API文档 https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-中进行实际实施可能会更容易 他们正在用它来产生多头流。就像问题中一样,您的来源可以是“ 0”。

long nextLong(long origin, long bound) {
  long r = nextLong();
  long n = bound - origin, m = n - 1;
  if ((n & m) == 0L)  // power of two
    r = (r & m) + origin;
  else if (n > 0L) {  // reject over-represented candidates
    for (long u = r >>> 1;            // ensure nonnegative
         u + m - (r = u % n) < 0L;    // rejection check
         u = nextLong() >>> 1) // retry
        ;
    r += origin;
  }
  else {              // range not representable as long
    while (r < origin || r >= bound)
      r = nextLong();
  }
  return r;
}

答案 12 :(得分:0)

使用r.nextDouble()的方法应使用:

long number = (long) (rand.nextDouble()*max);


long number = x+(((long)r.nextDouble())*(y-x));

答案 13 :(得分:0)

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;
}

答案 14 :(得分:0)

如果可以使用Java流,则可以尝试以下操作:

     function HelloUser() {
       const props = {Name: 'ABC', City: 'XYZ'};
       return <Hello {...props} />;
     }

这将在给定范围内生成数字。

答案 15 :(得分:0)

import java.util*;

    Random rnd = new Random ();
    long name = Math.abs(rnd.nextLong());

这应该有效

答案 16 :(得分:-3)

//使用系统时间作为种子值来获得一个好的随机数

   Random random = new Random(System.currentTimeMillis());
              long x;
             do{
                x=random.nextLong();
             }while(x<0 && x > n); 

//循环直到得到一个大于或等于0且小于n的数字