sourcecode

Java: 0 <= x < n 범위의 난수

copyscript 2022. 8. 31. 22:48
반응형

Java: 0 <= x < n 범위의 난수

랜덤 클래스에는 지정된 범위에서 랜덤 int를 생성하는 메서드가 있습니다.예를 들어 다음과 같습니다.

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

그러면 0 이상의 100 미만의 int 번호가 생성됩니다.긴 번호로도 똑같이 하고 싶어요.

long y = magicRandomLongGenerator(100);

랜덤 클래스에는 nextLong()만 있지만 범위를 설정할 수 없습니다.

Java 7(또는 Android API Level 21 = 5.0+)부터는 직접 사용할 수 있습니다.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's answer)를 참조하거나 독자적인 솔루션을 구현합니다.nextLong(n).

https://docs.oracle.com/javase/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;
}

ThreadLocalRandom

ThreadLocalRandom 메서드가 있습니다.

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

0 이외의 원점을 필요로 하는 경우에도 있습니다.원점(포함)과 바운드(포함)를 통과합니다.

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

SplittableRandom 같은 것을 가지다nextLong방법 및 방법을 사용하여 재현 가능한 숫자 시퀀스를 원하는 경우 시드를 선택할 수 있습니다.

(유틸리티 방식 없이) 범위 내에서 숫자를 생성하는 표준 방법은 범위와 함께 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(표준)까지의 긴 값을 제공합니다.

주의: 길게 캐스팅하는 것이 곱셈보다 우선 순위가 높기 때문에 괄호를 선택하십시오.

위의 방법은 매우 효과적입니다.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)

'%' 연산자 사용

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

'%' 연산자를 사용하여 최대값으로 나눈 나머지를 취합니다.그러면 0(포함)부터 제수(포함)까지의 숫자만 남습니다.

예를 들어 다음과 같습니다.

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

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

[0] 범위의 된 의사 m을 modulo absolute method와 nextLong()을 사용하다

Math.abs(rand.nextLong()) % m;

서 ★★★★★rand닥치는 대로 하다.

모듈로 연산자는 두 숫자를 나누고 나머지 숫자를 출력합니다.를 들어, 「」라고 하는 것은,3 % 213을 2로 하다

★★nextLong() 그합니다.[-(2^48, 2^48)](이 경우)는, 그 .이 경우 절대값을 구해야 합니다.않으면, 렇지ulul의 로, 그 if if if의 nextLong()가 음의 값을50%로은 [0, 0, 0, 0, 50 %]의범위를 .m를 참조해 주세요.

처음에 요청한 것은 [0,100] 범위의 균등하게 분산된 의사 난수였습니다.다음과 같은 코드를 사용합니다.

Math.abs(rand.nextLong()) % 100;

이거 어때:

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

?

다음 메서드는 100000000 ~999999 사이의 값을 반환합니다.

long min = 1000000000L
long max = 9999999999L    

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

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

}

Java 8 API에서

Longs 스트림을 생성하기 위해 사용하고 있는 API doc 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;
}

랜덤 페이지:

nextLong 메서드는 다음과 같이 랜덤 클래스에 의해 구현됩니다.

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

Random 클래스는 48비트만의 시드를 사용하기 때문에 이 알고리즘은 가능한 모든 긴 값을 반환하지 않습니다.

만약 이 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ를 받고 싶다면Long64번입니다.

제곱에 의 제곱을 것이 .Long에서처럼요, 이렇게

next(32) + ((long)nextInt(8) << 3)

예를 들어 35비트 범위를 얻습니다.

「」를 사용하는 r.nextDouble()★★★★★★★★★★★★★★★★★★:

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


long number = x+(((long)r.nextDouble())*(y-x));
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;
}

Java 스트림을 사용할 수 있는 경우 다음을 시도할 수 있습니다.

Random randomizeTimestamp = new Random();
Long min = ZonedDateTime.parse("2018-01-01T00:00:00.000Z").toInstant().toEpochMilli();
Long max = ZonedDateTime.parse("2019-01-01T00:00:00.000Z").toInstant().toEpochMilli();
randomizeTimestamp.longs(generatedEventListSize, min, max).forEach(timestamp -> {
  System.out.println(timestamp);
});

그러면 longs에 대해 지정된 범위의 숫자가 생성됩니다.

import java.util*;

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

이거면 될 것 같아

//시스템 시간을 시드 값으로 사용하여 적절한 난수를 얻습니다.

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

//0 이상 n보다 작은 수치를 얻을 때까지 루프합니다.

언급URL : https://stackoverflow.com/questions/2546078/java-random-long-number-in-0-x-n-range

반응형