Die Zufallsklasse verfügt über eine Methode zum Generieren von Zufalls-Int in einem bestimmten Bereich. Beispielsweise:
Random r = new Random();
int x = r.nextInt(100);
Dies würde eine int-Zahl erzeugen, die größer oder gleich 0 und kleiner als 100 ist. Ich möchte genau dasselbe mit einer langen Zahl tun.
long y = magicRandomLongGenerator(100);
Die zufällige Klasse hat nur nextLong (), erlaubt jedoch nicht, den Bereich festzulegen.
java
random
range
long-integer
Vilius Normantas
quelle
quelle
java.util.Random
Verwendet nur eine 48-Bit-Verteilung (siehe Implementierungsdetails), daher gibt es keine Normalverteilung.Antworten:
Ab Java 7 (oder Android API Level 21 = 5.0+) können Sie direkt
ThreadLocalRandom.current().nextLong(n)
(für 0 ≤ x <n) undThreadLocalRandom.current().nextLong(m, n)
(für m ≤ x <n) verwenden. Siehe @ Alex ‚s Antwort zum Detail.Wenn Sie mit Java 6 (oder Android 4.x) nicht weiterkommen , müssen Sie eine externe Bibliothek verwenden (
org.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1)
siehe z . B. die Antwort von @mawaldne ) oder eine eigene implementierennextLong(n)
.Laut https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html
nextInt
ist implementiert alsWir können dies also ändern, um Folgendes auszuführen
nextLong
:quelle
rng.nextLong() % n
einheitliche Werte erhalten werden (vorausgesetzt, alle Bits sind gut). Sie können diesen Teil ignorieren, wenn Sie möchten.m <= x <= n
, wie würden Sie Ihre Lösung ändern?m
undn
kann mit einer Zufallszahl zwischen0
und erhalten werdenn-m
, dann addierenm
.ThreadLocalRandom
ThreadLocalRandom
hat einenextLong(long bound)
Methode.Es hat auch,
nextLong(long origin, long bound)
wenn Sie einen anderen Ursprung als 0 benötigen. Übergeben Sie den Ursprung (einschließlich) und die Grenze (exklusiv).SplittableRandom
hat die gleichennextLong
Methoden und ermöglicht es Ihnen, einen Startwert auszuwählen, wenn Sie eine reproduzierbare Folge von Zahlen wünschen.quelle
Die Standardmethode zum Generieren einer Zahl (ohne Dienstprogrammmethode) in einem Bereich besteht darin, einfach das Doppelte mit dem Bereich zu verwenden:
gibt Ihnen eine lange zwischen 0 (einschließlich) und Bereich (exklusiv). Ebenso, wenn Sie eine Zahl zwischen x und y wollen:
erhalten Sie eine lange von 1234567 (einschließlich) bis 123456789 (exklusiv)
Hinweis: Überprüfen Sie die Klammern, da das Casting auf Long eine höhere Priorität als die Multiplikation hat.
quelle
bound
muss es kleiner sein als die größte Ganzzahl, die in einem Doppel codiert werden kann, 2 ^ 53.Die oben genannten Methoden funktionieren hervorragend. Wenn Sie Apache Commons (org.apache.commons.math.random) verwenden, lesen Sie RandomData. Es gibt eine Methode: nextLong (lang unten, lang oben)
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)
quelle
Verwenden Sie den Operator '%'
Mit dem Operator '%' nehmen wir den Rest, geteilt durch Ihren Maximalwert. Dies lässt uns nur Zahlen von 0 (einschließlich) bis zum Divisor (exklusiv).
Beispielsweise:
quelle
if (max == min)
if (nextLong() >= 0)
min = 0
undmax = 2 * (MAX_LONG / 3)
, dann erhalten Sie doppelt so häufig einen Wert[0, MAX_LONG / 3]
wie einen[MAX_LONG / 3, 2 * (MAX_LONG / 3)]
.nextLong
ein negativer Wert zurückgegeben wird, ist der Rest negativ und der Wert liegt außerhalb des Bereichs.Weitere Verbesserung der Antwort von kennytm: Eine Implementierung der Unterklasse unter Berücksichtigung der tatsächlichen Implementierung in Java 8 wäre:
quelle
if ((bound & m) == 0) { r = (bound * r) >> (Long.SIZE - 1); }
Erstens ist es mit Komponententests leicht zu zeigen, dass dies tatsächlich keine Zahlen im Bereich [0, gebunden] erzeugt. Zweitens ist es unnötig aufwendig:r = r & m
würde das gewünschte Ergebnis erzielen, und genau das macht die aktuelle Java 8-Implementierung. Es ist möglich, dass die Implementierung anders war, als diese Antwort geschrieben wurde, aber es kann nicht das gewesen sein, was gezeigt wurde.Wenn Sie eine gleichmäßig verteilte Pseudozufallslänge im Bereich von [0,
m
) wünschen , verwenden Sie den Modulo-Operator und die Absolutwertmethode in Kombination mit der folgendennextLong()
Methode:Wo
rand
ist dein zufälliges Objekt?Der Modulo-Operator teilt zwei Zahlen und gibt den Rest dieser Zahlen aus. Zum Beispiel
3 % 2
ist ,1
da der Rest von 3 und 2 : 1.Da
nextLong()
ein gleichmäßig verteiltes Pseudozufall im Bereich von [- (2 ^ 48), 2 ^ 48) (oder irgendwo in diesem Bereich) erzeugt wird, müssen Sie den absoluten Wert davon nehmen. Wenn Sie dies nicht tun, hat das Modulo dernextLong()
Methode eine 50% ige Chance, einen negativen Wert zurückzugeben, der außerhalb des Bereichs [0,] liegtm
.Was Sie ursprünglich angefordert haben, war eine gleichmäßig verteilte Pseudozufallslänge im Bereich von [0,100]. Der folgende Code tut dies:
quelle
Wie wäre es damit:
?
quelle
Die folgende Methode gibt einen Wert zwischen 10000000000 und 9999999999 zurück
quelle
Von der Java 8 API
Es könnte einfacher sein, die tatsächliche Implementierung aus dem API-Dokument https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long- zu übernehmen, für das sie es verwenden Longs Stream generieren. Und Ihr Ursprung kann wie in der Frage "0" sein.
quelle
Von der Seite auf Random :
Wenn Sie also eine erhalten möchten, erhalten
Long
Sie bereits nicht die volle 64-Bit-Reichweite.Ich würde vorschlagen, dass Sie, wenn Sie eine Reichweite haben, die nahe einer Potenz von 2 liegt, die
Long
in diesem Snippet wie folgt aufbauen:um beispielsweise einen 35-Bit-Bereich zu erhalten.
quelle
Die Methoden, die
r.nextDouble()
das verwenden, sollten Folgendes verwenden:quelle
quelle
Random
Instanzen bei hoc erstellen , Sie sollten keineThrowable
s oder andere Ausnahmen abfangen, wenn dies nicht erforderlich ist. Sie sollten Fehler mit einer Art Protokollierungsframework (z. B. SLF4J) protokollieren, anstatt sie zu verwendenprintStackTrace
.Wenn Sie Java-Streams verwenden können, können Sie Folgendes versuchen:
Dadurch werden für Longs Zahlen im angegebenen Bereich generiert.
quelle
Das sollte funktionieren
quelle
// Verwenden Sie die Systemzeit als Startwert, um eine gute Zufallszahl zu erhalten
// Schleife, bis eine Zahl größer oder gleich 0 und kleiner als n ist
quelle
n
ist, wenn 1 ist oder 2 sagen? Die Schleife führt viele Iterationen durch.