Cplusplus Zufallszahlen



  • Hey Leute,
    meine Frage wie kann ich in C++ Zufallszahlen generieren bin noch ziemlich am anfang mit C++ gerade bei der do-while Schleife angekommen.
    Und bitte den Zufallszahlen Generator auch erklären weil da habe ich meine Probleme finde zwar was auf Google aber weiß es nicht anzuwenden.
    Ich erhoffe mir hier mehr. 🙂

    Gruß
    Skeptar


  • Mod

    Es gibt da zwei verschiedene Wege:
    1. Der C++-Weg. Der ist allgemein zu empfehlen, hat jedoch den Nachteil ziemlich stark durchdesigned zu sein, mit allem was die Sprache C++ bietet. Deiner Selbsteinschätzung nach wirst du damit höchstwahrscheinlich nicht zurecht kommen. Referenzen mit Beispielen kannst du hier finden:
    http://www.cplusplus.com/reference/random
    http://en.cppreference.com/w/cpp/numeric/random

    2. Der C-Weg. Hat zwei Schwächen: Erstens hat der Zufallsgenerator einen globalen Zustand, das heißt, wenn irgendwo im Programm Zufallszahlen gezogen werden, dann hat dies Auswirkungen darauf, welche Zufallszahlen anderswo gezogen werden. Zweitens ist die Implementierung nicht vorgegeben, das kann auch ein schwacher Generator sein, der sich zum Beispiel nicht für wissenschaftliche Anwendungen eignet.
    Wenn du gerade nur Bahnhof verstehst, dann bedeutet das wahrscheinlich, dass keiner dieser Nachteile dich betrifft und du die C-Methode benutzen kannst. Dann findest du hier wieder Referenzen mit Beispielen:
    http://www.cplusplus.com/reference/cstdlib/rand
    http://en.cppreference.com/w/cpp/numeric/random/rand
    Mit rand() wird eine Zufallszahl (Integer) zwischen 0 und RAND_MAX (inklusive) erzeugt (RAND_MAX ist eine fest von der Implementierung vorgegebene Zahl, die du nicht ändern kannst. Diese Zahl willst du höchstwahrscheinlich noch so umrechnen, dass sie in einem für dich passenden Bereich liegt. Addition, Division und Modulorechnungen sind also angesagt. Der Zufallsgenerator hat, wie gesagt, einen globalen Zustand. Dieser ist bei jedem Programmstart der gleiche, das heißt, jedes Mal werden exakt die gleichen Zahlen gezogen. Mit srand kannst du den Zustand setzen. Eine einfache Möglichkeit, um (in gewissen Grenzen) bei jedem Programmstart andere Zufallszahlen zu erzeugen (sofern du das denn möchtest) ist, srand mit der aktuellen Uhrzeit (erhältlich mit time(0), Header ctime) aufzurufen.

    Siehe auch:
    http://www.c-plusplus.net/forum/172876
    und
    http://www.c-plusplus.net/forum/244661

    Allgemein ist das Thema ein bisschen anspruchsvoll. Zwar nicht sehr, aber man sollte schon wenigstens die Grundlagen der Sprache beherrschen und das while-Schleifen bedeuten, dass du praktisch noch gar nichts weißt. Ich würde an deiner Stelle noch ein paar Tage bis Wochen warten, bis du mit den Grundlagen sicherer bist.



  • 236 34259 1231 78 234678 4 2376423462 1 782364 5678 80 72495 17364 93254 9353721



  • #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
    	srand((unsigned)time(NULL)); // Zufallsgenerator initialisieren.
    
    	do
    	{
    		puts("Willst du eine Zufallszahl sehen? Dann druecke Enter.");
    		if ( '\n' == getchar())
    			printf("Guckst du hier:  %d\n", rand());	// Eine Zufallszahl ausgeben.
    		else // nicht berta
    			break;
    
    	} while(1);
    	return 0;
    }
    


  • wie du siehst, sind es lediglich zwei funktionsaufrufe, die etwas mit zufallszahlen zu tun haben.
    bevor dir noch jemand rät ein paar jahre zu warten, schätze lieber selbst ab ob du dich an diesen programmieraufwand vielleicht doch jetzt schon heranwagst.



  • Wir sind im C++ Forum...



  • Danke für die schnellen Antworten 😃
    Nur wie gesagt bin neu und kapiere 1% von deinem Text SeppJ.
    Nix da-hier genau so wollte ich es haben mit ein wenig erklärung und wenn geht in C++ da ich nicht weiß ob das :

    srand((unsigned)time(NULL)); // Zufallsgenerator initialisieren.
    

    auch in C++ gilt... .

    Gruß
    Skeptar



  • Sorry für die vielen Rechtschreibfehler fallen mir immer erst am Ende auf und dann ist es zu spät da ich mich noch angemeldet habe um diese zu ändern. :p



  • Skeptar schrieb:

    Nix da-hier genau so wollte ich es haben mit ein wenig erklärung und wenn geht in C++ da ich nicht weiß ob das :

    srand((unsigned)time(NULL)); // Zufallsgenerator initialisieren.
    

    der initialisierungswert bestimmt die zahlenfolge, die von der funktion rand geliefert wird.
    wenn du den selben initialisierungswert verwendest, bekommst du dieselbe zahlenfolge.
    hier wird mit einem zahlenwert initialisiert, der von der funktion time geliefert wird.
    die funktion time liefert die anzahl der vergangenenen sekunden seit 1970.
    http://www.cplusplus.com/reference/ctime/time/

    #include <iostream>
    #include <ctime>
    using namespace std;
    
    int main(void)
    {
    	srand(1); // Zufallsgenerator mit 1 initialisieren.
    	for ( int i = 0; i < 10; i++ )
    		cout << rand() << endl;
    
    	srand(1); // Zufallsgenerator mit 1 initialisieren.
    	for ( int i = 0; i < 10; i++ )
    		cout << rand() << endl;
    
    	// Es wurde zweimal mit dem selben Wert initialisiert, daher wurde 'zufällig' zweimal dieselbe
    	// Zahlenfolge ausgegeben.
    
    	srand((unsigned)time(NULL)); // Zufallsgenerator mit den seit 1970 vergangenen Sekunden initialisieren.
    
        do
        {
            cout << "Willst du eine Zufallszahl sehen? Dann druecke Enter." << endl;
    		if ( '\n' == cin.get())
    			cout << rand() << endl;
            else 
                break;
        } while(true);
        return 0;
    }
    


  • Also wenn ich das nun richtig verstehe würde dies:

    srand(1); // Zufallsgenerator mit 1 initialisieren.
        for ( int i = 0; i < 10; i++ )
    

    ausreichen um eine Zufallszahl zu generieren.
    Wenn ja könntest du mir das eventuell etwas deutlicher erklären warum dort eine Schleife und wie kann man das einstellen das eine Zahl zwischen z.B. 1 und 100 generiert wird?.

    Skeptar



  • Skeptar schrieb:

    Also wenn ich das nun richtig verstehe würde dies:

    srand(1); // Zufallsgenerator mit 1 initialisieren.
        for ( int i = 0; i < 10; i++ )
    

    ausreichen um eine Zufallszahl zu generieren.
    Wenn ja könntest du mir das eventuell etwas deutlicher erklären warum dort eine Schleife und wie kann man das einstellen das eine Zahl zwischen z.B. 1 und 100 generiert wird?.

    Skeptar

    die schleife hat nichts mit der initialisierung zu tun, in der schleife werden lediglich die zahlen ausgegeben.
    zur erzeugung der zahlen brauchst du srand auch nicht, aber das hat ja seppj schon recht ausführlich erklärt.
    für das einstellen der zahlen zwischen 1 und 100 wird dir gleich jemand ein beispiel posten, sonst mach ich das später nach dem essen.



  • Stephan T. Lavavej hat erst kürzlich einen kurzen 30 minuten vortrag gehlaten, über zufallszahlen
    fand ich sehr informativ

    http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful



  • zufallszahlen zwischen 1 und 100(erster googletreffer fuer "c++ rand()"^^)

    rand() % 100 + 1;
    


  • und der Link über dir sagt dir schon, dass das nicht korrekt ist 😉

    int maxUsable = RAND_MAX - RAND_MAX%100;
    int number = 0;
    do{
        number = rand();
    }while(number > maxUsable);
    number = number % 100+1;
    


  • keine lust mir das vid anzugucken, aber

    int main()
    {
    	int nummer;
    	for(long i=0;i<10000000;i++)
    	{
    		nummer=rand()%100+1;
    		if (nummer>100 || nummer<1) cout<<"otze hat recht";
    
    	}
    }
    

    😃



  • Und dann noch mal in "richtig": 🤡

    #include <array>
    #include <algorithm>
    #include <random>
    #include <iostream>
    
    std::mt19937 create_seeded_rng()
    {
    	std::random_device rd;
    	std::array<std::mt19937::result_type, std::mt19937::state_size> seed_data;
    	std::generate(seed_data.begin(), seed_data.end(), std::ref(rd));
    	std::seed_seq seq(seed_data.begin(), seed_data.end());
    	return std::mt19937(seq);
    }
    
    int main()
    {
    	std::mt19937 rng = create_seeded_rng();
    	std::uniform_int_distribution<int> dist(0, 100);
    
    	for (unsigned i = 0; i != 100; ++i)
    		std::cout << dist(rng) << '\n';
    }
    


  • Modulo ist oft gut genug.



  • bert0 schrieb:

    keine lust mir das vid anzugucken

    merkt man. Modulo gibt dir keine Gleichverteilung.

    @cooky451

    std::mt19937 create_seeded_rng()
    {
        std::random_device rd;
        return std::mt19937(rd);
    }
    


  • Leute....
    es ist ja nett das ihr so viele Antworten schreibt,
    aber ihr vergesst das entscheidene, dass ich neu in C++ bin 😃
    Ich wollte eigentlich nur eine Zufallszahl in einer Variable speichern um daraus ein Ratespiel zu erstellen..... .
    Also geht das alles noch viel einfacher`??? 😃

    Skeptar



  • @otze Ich glaube nicht dass man dem nen Generator als seed-seq geben kann?


Anmelden zum Antworten