Frage

Der folgende Code ausgibt, eine Zufallszahl in jeder Sekunde:

int main ()
{
    srand(time(NULL)); // Seeds number generator with execution time.

    while (true)
    {
        int rawRand = rand();

        std::cout << rawRand << std::endl;

        sleep(1);
    }
}

Wie kann ich Größe diese Zahlen nach unten, so sind sie immer im Bereich von 0-100?

War es hilfreich?

Lösung

Wenn Sie C ++ verwenden und sind besorgt über eine gute Verteilung können Sie TR1 C ++ 11 <random>.

#include <random>

std::random_device rseed;
std::mt19937 rgen(rseed()); // mersenne_twister
std::uniform_int_distribution<int> idist(0,100); // [0,100]

std::cout << idist(rgen) << std::endl;

Andere Tipps

Alle Beispiele geschrieben bisher tatsächlich schlecht verteilt Ergebnisse. Führen Sie den Code häufig und erstellen eine Statistik, um zu sehen, wie die Werte verzerrt werden.

Eine bessere Möglichkeit, einen echten zu erzeugen einheitliche Zufallszahlenverteilung in jedem Bereich [0, N ] der folgenden (unter der Annahme, dass rand tatsächlich eine gleichmäßige Verteilung folgt, die bei weitem nicht offensichtlich ist):

unsigned result;
do {
    result = rand();
} while (result > N);

Natürlich ist das Verfahren langsam, aber es nicht produziert eine gute Verteilung. Ein etwas smarter Weg, dies zu tun, ist das größte Vielfache von N zu finden, die kleiner als RAND_MAX ist und die Verwendung dieser als die oberen Grenze. Danach kann man sicher die result % (N + 1) nehmen.

Für eine Erklärung Warum die naiven Modulverfahren ist schlecht und warum die oben besser ist, siehe Julienne ausgezeichneter Artikel über mit rand .

int rawRand = rand() % 101;

See (für weitere Details):

rand - C ++ Referenz

Andere haben auch darauf hingewiesen, dass dies nicht Ihr wird die beste Verteilung von Zufallszahlen geben möglich. Wenn diese Art von Sache wichtig in Ihrem Code ist, würden Sie tun müssen:

int rawRand = (rand() * 1.0 / RAND_MAX) * 100;

Bearbeiten

Drei Jahre, ich bin bearbeitet zu machen. Wie andere schon erwähnt, hat rand() viele Fragen. Offensichtlich kann ich nicht seine Verwendung empfehlen, wenn es vorwärts gehen bessere Alternativen gibt. Sie können hier alles über die Details und Empfehlungen lesen:

rand () als schädlich | GoingNative 2013

Sie können tun,

cout << rawRand % 100 << endl; // Outputs between 0 and 99

cout << rawRand % 101 << endl; // outputs between 0 and 100

Für die Menschen, Downvoting; 1 Minute beachten Sie danach ursprünglich gepostet ich den Kommentar verfasst:

http://www.cplusplus.com/reference/clibrary/cstdlib/rand „Beachten sie aber, dass diese Modulo-Operation erzeugt keine wirklich gleichmäßig verteilte Zufallszahl in der Spanne (da in den meisten Fällen niedrigeren Zahlen sind etwas häufiger), aber es ist in der Regel eine gute Näherung für kurze Spannweiten.“

mit 64-Bit-Ganzzahlen und unter Verwendung von 100 Zahlen als Ausgabe, werden die Zahlen 0-16 mit 1,00000000000000000455% der Zahlen dargestellt (eine relative Genauigkeit zu identisch verteilt von 1% um etwa 10 -18 ), während die Nummern 17-99 mit ,99999999999999999913% der Zahlen dargestellt werden. Ja, nicht perfekt verteilt, aber eine sehr gute Näherung für kleine Spannweiten.

Beachten Sie auch, wo fragt die OP für identisch verteilte Zahlen? Für alle wissen, dass wir diese für Zwecke verwendet werden, wo eine kleine Abweichungen spielt keine Rolle (zB etwas anderes als Kryptographie - und wenn sie die Zahlen für Kryptographie diese Frage verwenden, ist viel zu naiv für sie, ihre eigene Kryptographie schriftlich zu ).

Bearbeiten - Für Menschen, die eine gleichmäßige Verteilung von Zufallszahlen mit mit dem folgenden Code funktionieren wirklich betroffen sind. Hinweis: Dies ist nicht unbedingt optimal wie mit 64-Bit-Zufall Ints, wird es erfordert zwei Anrufe von rand() einmal alle 10 ^ 18 Anrufen.

unsigned N = 100; // want numbers 0-99
unsigned long randTruncation = (RAND_MAX / N) * N; 
// include every number the N times by ensuring rawRand is between 0 and randTruncation - 1 or regenerate.
unsigned long rawRand = rand();

while (rawRand >= randTruncation) {
    rawRand = rand();  
// with 64-bit int and range of 0-99 will need to generate two random numbers
// about 1 in every (2^63)/16 ~ 10^18 times (1 million million times)

// with 32-bit int and range of 0-99 will need to generate two random numbers 
// once every 46 million times.

}
cout << rawRand % N << stdl::endl;

Siehe man 3 rand -. Sie maßstab müssen von durch RAND_MAX Division den Bereich [0, 1], nach dem Sie kann mit 100 multiplizieren für Ihren Zielbereich zu erhalten

Für den Bereich min bis max (inklusive), Verwendung: int result = rand() % (max - min + 1) + min;

Wie lange eine Antwort Sie möchten.

ist die einfachste mit dem Rest zu konvertieren, wenn sie durch 101 geteilt:

int value = rawRand % 101;

Ein semipurist würde rescale verdoppelt werden:

double dbl = 100 * ((double)rawRand / RAND_MAX);
int ivalue = (int)(dbl + 0.5);   // round up for above 0.5

Und ein Purist würde sagen, dass rand erzeugt keine Zufallszahl.

Für Ihre Informationen, die Qualität der Zufallszahlen wird berechnet, indem eine Folge von Zahlen gemessen und dann die mathematische Wahrscheinlichkeit Berechnung, dass die Quelle dieser Reihenfolge zufällig war. Der einfache Hack der Rest ist eine sehr schlechte Wahl verwenden, wenn Sie nach dem Zufall sind.

Einige Leute haben den folgenden Code als Beispiel geschrieben:

int rawRand = (rand() / RAND_MAX) * 100;

Dies ist ein ungültiger Weg, um das Problem zu lösen, da sowohl rand () und RAND_MAX ganze Zahlen sind. In C ++, diese Ergebnisse in ganzzahligen Division, die die Ergebnisse gestutzt werden Dezimalstellen. Als RAND_MAX> = rand (), ist das Ergebnis dieser Operation entweder 1 oder 0, was bedeutet, rawRand kann dies nur 0 oder 100. Eine richtige Weg sein, Sie folgendermaßen vorgehen würde:

int rawRand = (rand() / static_cast<double>(RAND_MAX)) * 100;

Da man die Operanden nun eine doppelte, Gleitkommadivision verwendet wird, der einen geeigneten Wert zwischen 0 und 1 zurückkehren würde.

rawRand% 101 geben würde [0-100], inklusive.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top