Java: au hasard le numéro de long en 0 <= x < n gamme
Aléatoire de la classe a une méthode pour générer de l'aléatoire int dans une plage donnée. Par exemple:
Random r = new Random();
int x = r.nextInt(100);
Ce serait de générer un int nombre plus ou égal à 0 et inférieur à 100. Je voudrais faire exactement la même chose avec le numéro de long.
long y = magicRandomLongGenerator(100);
Aléatoire classe a seulement nextLong(), mais il ne permet pas de la plage définie.
- , Peut être utile: stackoverflow.com/questions/2290057/...
- Avez-vous considéré comme juste l'obtention de votre long aléatoire et en prenant le mod de votre gamme? (Bien sûr, si la plage est à seulement 100 j'avais produire un int aléatoire, et de le jeter à la longue.)
java.util.Random
n'utilise que de 48 bits de distribution (voir les détails de mise en œuvre), afin de ne pas avoir une distribution normale.- Dans les temps modernes, on pourrait envisager d'utiliser org.apache.commons.lang3.RandomUtils#nextLong.
Vous devez vous connecter pour publier un commentaire.
À partir de Java 7 (ou de l'API Android Niveau 21 = 5.0+), vous pouvez l'utiliser directement
ThreadLocalRandom.current().nextLong(n)
(pour 0 ≤ x < n) etThreadLocalRandom.current().nextLong(m, n)
(pour m ≤ x < n). Voir @Alex's réponse pour plus de détails.Si vous êtes coincé avec Java 6 (ou Android 4.x) vous avez besoin d'utiliser une bibliothèque externe (par exemple,
org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1)
, voir @mawaldne's réponse), ou mettre en place votre proprenextLong(n)
.Selon http://java.sun.com/j2se/1.5.0/docs/api/java/util/Random.html
nextInt
est mis en œuvre commeDonc on peut le modifier pour effectuer
nextLong
:rng.nextLong() % n
sera de donner des valeurs uniformes (à supposer tous les bits sont bons). Vous pouvez ignorer cette partie si vous voulez.m <= x <= n
, comment voulez-vous modifier votre solution?m
etn
peut être obtenue avec un nombre aléatoire entre0
etn-m
, puis ajouterm
.La méthode standard pour générer un nombre (sans une méthode utilitaire) dans une plage est juste d'utiliser le double de la gamme:
vous donnera une longue entre 0 (inclus) et la plage (exclusif). De même, si vous voulez un nombre compris entre x et y:
vous donnera une longue de 1234567 (inclus) par 123456789 (exclusif)
Remarque: vérifiez parenthèses, parce que la coulée de long a une plus grande priorité que la multiplication.
bound
devra être de moins que le plus grand entier qui peuvent être codés en double, 2^53.ThreadLocalRandom
ThreadLocalRandom
a unnextLong(long lié)
méthode.Il a également
nextLong(long origine, longtemps lié)
si vous avez besoin d'une origine autre que 0. Passer l'origine (inclus) et la limite (exclusif).SplittableRandom
a la mêmenextLong
méthodes et vous permet de choisir une valeur initiale si vous voulez une reproductibilité de la séquence de nombres.ThreadLocalRandom
sur mon radar.Les méthodes ci-dessus fonctionne parfaitement. Si vous utilisez apache commons (org.apache.commons.les mathématiques.aléatoire) découvrez RandomData. Il a une méthode: nextLong(long bas, de long en haut)
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)
Utiliser le '%' opérateur
En utilisant le '%' opérateur, nous prenons le reste quand divisé par votre valeur maximale. Ce qui nous laisse avec seulement un nombre compris entre 0 (inclus) au diviseur (exclusif).
Par exemple:
if (max == min)
if (nextLong() >= 0)
min = 0
etmax = 2 * (MAX_LONG / 3)
, alors vous êtes deux fois plus de chances d'obtenir une valeur en[0, MAX_LONG / 3]
que vous êtes pour obtenir un dans[MAX_LONG / 3, 2 * (MAX_LONG / 3)]
.nextLong
renvoie une valeur négative, le reste sera négatif, et la valeur est en dehors de la plage.Merci beaucoup pour ce post. C'est juste ce dont j'avais besoin. Devais changer quelque chose pour obtenir la partie que j'ai l'habitude de travailler.
J'ai eu la suivante (inclus ci-dessus):
de travail en modifiant à:
depuis
(long)r.nextDouble()
est toujours à zéro.Si vous voulez un pseudo-aléatoires uniformément distribués longtemps dans la plage de [0,
m
), essayez d'utiliser l'opérateur modulo et la valeur absolue de la méthode combinée avec lanextLong()
méthode comme on le voit ci-dessous:Où
rand
est votre objet Aléatoire.L'opérateur modulo divise deux nombres et renvoie le reste de ces numéros. Par exemple,
3 % 2
est1
parce que le reste de 3 et 2 est 1.Depuis
nextLong()
génère un pseudo-aléatoires uniformément distribués longtemps dans la gamme de [-(2^48),2^48) (ou quelque part dans cette gamme), vous aurez besoin de prendre la valeur absolue d'elle. Si vous ne le faites pas, le modulo de lanextLong()
méthode a 50% de chance de renvoyer une valeur négative, ce qui est hors de l'intervalle [0,m
).Ce qui vous a été distribuée uniformément pseudo longtemps dans la gamme de [0,100). Le code suivant: les
De la page sur Aléatoire:
Donc, si vous voulez obtenir un
Long
, vous êtes déjà ne va pas pour obtenir la pleine 64 bits de large.Je dirais que si vous avez une gamme qui tombe près d'une puissance de 2, vous construisez la
Long
comme dans cet extrait de code, comme ceci:pour obtenir un 35 bits de large, par exemple.
Améliorer encore kennytm réponse: Une sous-classe de mise en œuvre de la prise de la réelle mise en œuvre en Java 8 en compte seront:
Comment à ce sujet:
?
La Méthode ci-dessous va vous Renvoyer une valeur entre 10000000000 à 9999999999
De Java 8 API
Il pourrait être plus facile de prendre la réelle mise en œuvre de doc API https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-
ils l'utilisent pour générer des longs flux. Et votre origine peut être "0" comme dans la question.
Les méthodes à l'aide de la
r.nextDouble()
à utiliser:Random
les instances ad hoc, vous ne devriez pas prendreThrowable
s ou d'autres exceptions si non, vous devez le journal des erreurs avec certains type de journalisation (c'est à dire SLF4J) au lieu d'utiliserprintStackTrace
.//utilisation d'un système temps comme valeur de départ pour obtenir un bon nombre aléatoire
//Boucle jusqu'à obtenir un nombre supérieur ou égal à 0 et inférieur à n
n
est de 1, ou de dire 2? La boucle effectuera beaucoup itérations.