Случайный класс имеет метод для генерации случайных int в заданном диапазоне. Например:
Random r = new Random();
int x = r.nextInt(100);
Это сгенерирует целое число больше или равное 0 и меньше 100. Я хотел бы сделать то же самое с длинным числом.
long y = magicRandomLongGenerator(100);
Случайный класс имеет только nextLong (), но он не позволяет устанавливать диапазон.
java
random
range
long-integer
Вилюс Нормантас
источник
источник
java.util.Random
используется только 48-битное распределение (см. подробности реализации), поэтому оно не будет иметь нормального распределения.Ответы:
Начиная с 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 ) или реализовать свою собственнуюnextLong(n)
.Согласно https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html
nextInt
реализован какТаким образом, мы можем изменить это для выполнения
nextLong
:источник
rng.nextLong() % n
даст одинаковые значения (предположим, что все биты хороши). Вы можете игнорировать эту часть, если хотите.m <= x <= n
, как бы вы изменили свое решение?m
иn
может быть получено со случайным числом между0
иn-m
, затем добавьтеm
.ThreadLocalRandom
ThreadLocalRandom
естьnextLong(long bound)
метод.Он также имеет,
nextLong(long origin, long bound)
если вам нужен источник, отличный от 0. Передайте источник (включительно) и связанный (эксклюзив).SplittableRandom
имеет те жеnextLong
методы и позволяет вам выбрать начальное число, если вы хотите воспроизводимую последовательность чисел.источник
Стандартный метод генерации числа (без использования служебного метода) в диапазоне - просто использовать двойное с диапазоном:
даст вам длинный между 0 (включительно) и диапазон (эксклюзив). Точно так же, если вы хотите число между x и y:
выдаст вам длинную с 1234567 (включительно) до 123456789 (эксклюзив)
Примечание: проверьте круглые скобки, потому что приведение к long имеет более высокий приоритет, чем умножение.
источник
bound
должно быть меньше, чем наибольшее целое число, которое может быть закодировано в двойном, 2 ^ 53.Методы выше работают отлично. Если вы используете 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)
источник
Используйте оператор «%»
Используя оператор «%», мы берем остаток от деления на ваше максимальное значение. Это оставляет нам только цифры от 0 (включительно) до делителя (исключая).
Например:
источник
if (max == min)
if (nextLong() >= 0)
min = 0
иmax = 2 * (MAX_LONG / 3)
, тогда у вас вдвое больше шансов получить значение,[0, MAX_LONG / 3]
чем у вас[MAX_LONG / 3, 2 * (MAX_LONG / 3)]
.nextLong
возвращает отрицательное значение, остаток будет отрицательным, и значение будет вне диапазона.Дальнейшее улучшение ответа kennytm: Реализация подкласса с учетом фактической реализации в Java 8 будет:
источник
if ((bound & m) == 0) { r = (bound * r) >> (Long.SIZE - 1); }
первых, с помощью модульных тестов легко показать, что это на самом деле не дает числа в диапазоне [0, bound). Во-вторых, он излишне сложен:r = r & m
он достиг бы желаемого результата, и это в основном то, что делает текущая реализация Java 8. Возможно, что реализация была другой, когда был написан этот ответ, но это не могло быть тем, что показано.Если вам нужен равномерно распределенный псевдослучайный тип long в диапазоне [0,
m
), попробуйте использовать оператор по модулю и метод абсолютного значения в сочетании сnextLong()
методом, как показано ниже:Где
rand
твой случайный объект?Оператор по модулю делит два числа и выводит остаток от этих чисел. Например,
3 % 2
это1
потому , что остальная часть 3 и 2 равно 1.Так как
nextLong()
генерирует равномерно распределенное псевдослучайное длинное в диапазоне [- (2 ^ 48), 2 ^ 48) (или где-то в этом диапазоне), вам нужно будет принять его абсолютное значение. Если вы этого не сделаете, по модулюnextLong()
метода с вероятностью 50% можно вернуть отрицательное значение, выходящее за пределы диапазона [0,m
).Сначала вы запрашивали равномерно распределенный псевдослучайный тип в диапазоне [0,100). Следующий код делает это:
источник
Как насчет этого:
?
источник
Приведенный ниже метод вернет вам значение от 10000000000 до 9999999999
источник
Из Java 8 API
Может быть проще взять фактическую реализацию из документа API https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long - они используют его для генерировать длинный поток. И ваше происхождение может быть "0", как в вопросе.
источник
Со страницы в случайном порядке :
Так что если вы хотите получить
Long
, вы уже не собираетесь получить полный 64-битный диапазон.Я хотел бы предложить, что если у вас есть диапазон, который приближается к степени 2, вы создаете
Long
как в этом фрагменте, как это:например, чтобы получить 35-битный диапазон.
источник
Методы с использованием
r.nextDouble()
должны использовать:источник
источник
Random
экземпляры в hoc, вы не должны перехватыватьThrowable
s или другие исключения, если они не нужны, вы должны регистрировать ошибки с какой-либо структурой журналирования (например, SLF4J) вместо использованияprintStackTrace
.Если вы можете использовать потоки Java, вы можете попробовать следующее:
Это сгенерирует числа в заданном диапазоне для длинных позиций.
источник
Это должно работать
источник
// использовать системное время в качестве начального значения, чтобы получить хорошее случайное число
// Цикл, пока не получим число больше или равно 0 и меньше, чем n
источник
n
будет 1, или скажем 2? Цикл будет выполнять много итераций.