Java: случайное длинное число в 0
случайный класс имеет метод, чтобы генерировать случайные числа в заданном диапазоне. Например:
Random r = new Random();
int x = r.nextInt(100);
это будет генерировать число int больше или равно 0 и меньше 100. Я хотел бы сделать то же самое с длинным номером.
long y = magicRandomLongGenerator(100);
случайный класс имеет только nextLong (), но он не позволяет установить диапазон.
14 ответов:
начиная от Java 7 (или Android API Level 21 = 5.0+) вы можете напрямую использовать
ThreadLocalRandom.current().nextLong(n)(для 0 ≤ x ThreadLocalRandom.current().nextLong(m, n) (для m ≤ x @Alexответ для деталей.
если вы застряли с Java 6 (или Android 4.x) вы должны использовать внешнюю библиотеку (например,
org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1)см. @mawaldne's ответ), или реализовать свой собственный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; }
стандартный метод для генерации числа (без метода утилиты) в диапазоне-это просто использовать 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 имеет более высокий приоритет, чем умножение.
ThreadLocalRandom
ThreadLocalRandomестьnextLong(long bound)метод.long v = ThreadLocalRandom.current().nextLong(100);она также имеет
nextLong(long origin, long bound)если вам нужен более 0. Передайте начало координат (включительно) и границу (исключительно).long v = ThreadLocalRandom.current().nextLong(10,100); // For 2-digit integers, 10-99 inclusive.
SplittableRandomимеет одно и то жеnextLongметоды и позволяет выбрать семя, если вы хотите воспроизводимую последовательность чисел.
методы выше работают отлично. Если вы используете Apache commons (org.апаш.палата общин.математика.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()*(y-x));чтобы работать, изменив его на:
long number = x+ (long)(r.nextDouble()*(y-x));С
(long)r.nextDouble()всегда равен нулю.
если вы хотите равномерно распределенную псевдослучайную длину в диапазоне [0,
m), попробуйте использовать оператор по модулю и метод абсолютного значения в сочетании сnextLong()метод, как показано ниже:Math.abs(rand.nextLong()) % m;здесь
randваш случайный объект.оператор по модулю делит два числа и выводит остаток этих чисел. Например,
3 % 2и1потому что остаток от 3 и 2 равен 1.С
nextLong()создает равномерно распределенная псевдослучайная длина в диапазоне [-(2^48),2^48) (или где-то в этом диапазоне), вам нужно будет взять его абсолютное значение. Если вы этого не сделаете, то по модулюnextLong()метод имеет 50% шанс вернуть отрицательное значение, которое находится вне диапазона [0,m).то, что вы изначально просили, было равномерно распределенной псевдослучайной длиной в диапазоне [0,100). Следующий код делает это:
Math.abs(rand.nextLong()) % 100;
со страницы на 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-битный диапазон, например.
дальнейшее улучшение ответа кеннитма: реализация подкласса с учетом фактической реализации в 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; } }
Как насчет этого:
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())*(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; }
ниже метод вернет вам значение от 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; }
/ / используйте системное время в качестве начального значения, чтобы получить хорошее случайное число
Random random = new Random(System.currentTimeMillis()); long x; do{ x=random.nextLong(); }while(x<0 && x > n);//цикл, пока не получите число больше или равно 0 и меньше n
Comments