rand() und srand sind im Ergebnis zu unflexibel



  • Beim Versuch, mittels der Funktion rand() mehrere Zufallszahlen zwischen 1 ... 6 zu erzeugen, werden praktisch immer identische Ergebnisse geliefert. Dass rand() nur Pseudozufallszahlen generiert ist mir zwar bekannt, aber das Resultat ist eher niederschmetternd.
    Mit TurboPascal vor 25 Jahren gab es eine ähnliche Funktion, die wirklich sauber arbeitete. Auch da war es üblich, die Initialisierung mit der Systemzeit zu realisieren.

    Meine Funktion für das "Würfeln" sieht so aus, wobei ich mit 2 Varianten für srand getestet habe:

    int dice(void)
    {
    	time_t zeit;
    	srand((unsigned) time(NULL));
    //	srand((unsigned) time(&zeit));
    	return(1 + ( rand() % 6 ));
    
    }
    

    Im eigentlichen Programm muss die Funktion "dice" immer wieder 6 Würfel simulieren, wird also praktisch sechsmal nacheinander aufgerufen. Selbst eine Pause mit "Sleep(100)" ändert fast garnichts am Gleichklang der Ergebnisse.

    Ich denke bereits an die Möglichkeit, für jeden der Würfel eine andere Initialisierungsvariante zu finden. Gibt es Alternativen?



  • Du solltest srand einmal am Start des Programms aufrufen und nicht jedesmal den Zufallszahlengenerator neu initialisieren ...



  • Ja, rand() funktioniert in deinem Fall wohl wirklich niederschmetternd weil du srand(..) falsch benutzt 😉 Mit srand(..) kannst du den Pseudozufallsgenerator einen Startwert geben. Man sollte aber nur einmal einen Startwert (Seed-Wert) setzen.

    Das heisst

    srand((unsigned) time(NULL));
    

    sollte nur ein einziges Mal aufgerufen werden. Rufe diese Methode genau ein Mal am Anfang deiner main-Funktion auf.



  • Kommt irgendwie in letzter Zeit alles doppelt und dreifach kurz hintereinander?
    Erst drei Unicode-Threads, jetzt der zweite DRITTE random Thread, ...
    Was kommt als nächstes? Der zweite Anfängerprogrammiersprachenauswahl-Thread? Hoffentlich nicht.
    Schau mal ganz unten auf Seite 1 und relativ weit oben auf Seite 2, da findest du noch reichlich...



  • Jemand sollte ne Webseite machen, wo man nen Funktionsnamen eingeben/nachschlagen kann, und die Webseite listet dann die 1-2 "Standardfehler" die alle machen.

    Also bei rand() wären das dann z.B.:
    Fehler 1: nie srand() aufgerufen
    Fehler 2: srand() vor jedem Aufruf von rand()

    Bzw. bei recv():
    Fehler 1: recv(..., N, ...) aufgerufen, und sich darauf verlassen dass - so lange die nicht Verbindung abbricht - wirklich immer N Bytes gelesen werden.
    Fehler 2: int packetSize = recv(...);, und dann annehmen recv() würde genau die "Packetierung" zurückgeben mit der auf der anderen Seite send() aufgerufen wurde.

    Bei TerminateThread():
    Fehler 1: TerminateThread() wird irgendwo für irgendwas verwendet.

    uswusf.



  • hustbaer schrieb:

    Jemand sollte ne Webseite machen, wo man nen Funktionsnamen eingeben/nachschlagen kann, und die Webseite listet dann die 1-2 "Standardfehler" die alle machen.

    👍 Gute Idee, so etwas sollte es geben. Vielleicht allgemein über modernes C++.

    hustbaer schrieb:

    Fehler 1: TerminateThread() wird irgendwo für irgendwas verwendet.

    Das würde ich auch bei rand , recv und vielen weiteren Dingen hinschreiben. Natürlich jeweils mit Begründung.


  • Mod

    Fehler 1: TerminateThread() wird irgendwo für irgendwas verwendet.

    throw;
    

    *duck-und-weg*



  • TyRoXx schrieb:

    hustbaer schrieb:

    Jemand sollte ne Webseite machen, wo man nen Funktionsnamen eingeben/nachschlagen kann, und die Webseite listet dann die 1-2 "Standardfehler" die alle machen.

    👍 Gute Idee, so etwas sollte es geben. Vielleicht allgemein über modernes C++.

    Dummerweise hab' ich weder nen geeigneten Webspace noch wirklich Zeit...

    TyRoXx schrieb:

    hustbaer schrieb:

    Fehler 1: TerminateThread() wird irgendwo für irgendwas verwendet.

    Das würde ich auch bei rand , recv und vielen weiteren Dingen hinschreiben. Natürlich jeweils mit Begründung.

    Der Unterschied ist bloss dass man "TerminateThread() ist immer ein Fehler" begründen kann, "rand()/recv()/... ist immer ein Fehler" aber nicht. Weil deiner Meinung nach nicht gut != Fehler. Bzw. auch schlechter Stil != Fehler.

    @Arcoth
    Verstehe nicht was du meinst.
    Meinst du dass throw; böse ist? Oder... 😕
    (Weil throw; ist nämlich sehr sehr cool. Bloss nicht direkt innerhalb eines Catch-Blocks zum Exceptions weiter werfen. Wobei selbst das auch kein Fehler ist, sondern nur schlechter Stil.)


  • Mod

    hustbaer schrieb:

    Meinst du dass throw; böse ist? Oder... 😕

    Klar, ist es das denn nicht?

    (Weil throw; ist nämlich sehr sehr cool.)

    Ja? Und du benutzt das auch? Ist ja der Hammer, ich dachte, throw; wäre so ein Tabu.



  • hustbaer schrieb:

    (Weil throw; ist nämlich sehr sehr cool. Bloss nicht direkt innerhalb eines Catch-Blocks zum Exceptions weiter werfen. Wobei selbst das auch kein Fehler ist, sondern nur schlechter Stil.)

    Warum ist es schlechter Stil? Weil RAII dafür sorgen sollte, automatisch aufzuräumen und man daher kein try-catch-rethrow braucht, oder noch aus anderen Gründen?



  • std::string GetMessageFromCurrentException()
    {
        try
        {
            throw;
        }
        catch (std::exception const& e)
        {
            return ...
        }
        catch (_com_error const& e)
        {
            return ...
        }
        catch (CAtlException const& e)
        {
            return ...
        }
        catch (CException const* e)
        {
            return ...
        }
        ...
        ...
        ...
        catch (...)
        {
            return "WTF?!?";
        }
    }
    
    int main()
    {
        try
        {
            return TheRealProgram();
        }
        catch (...)
        {
            LogErrorOrSomething(GetMessageFromCurrentException());
            return 1;
        }
    }
    


  • Weiterwerfer schrieb:

    hustbaer schrieb:

    (Weil throw; ist nämlich sehr sehr cool. Bloss nicht direkt innerhalb eines Catch-Blocks zum Exceptions weiter werfen. Wobei selbst das auch kein Fehler ist, sondern nur schlechter Stil.)

    Warum ist es schlechter Stil? Weil RAII dafür sorgen sollte, automatisch aufzuräumen und man daher kein try-catch-rethrow braucht, oder noch aus anderen Gründen?

    Jain.
    Es geht um Fälle wo die Exception im Endeffekt dann keiner fängt.
    Ohne throw; crasht dir das Programm dann an der Stelle wo das erste, eigentliche throw steht.
    Mit throw; crasht es dort wo das throw; steht. Macht das Fehlersuchen recht lästig.

    Also weniger wegen "RAII ist so kuhl und muss überall rein", sondern mehr wegen "ich mag nicht blöd rumsuchen wenn ich's auch schneller finden kann, und dank RAII gibt's ne Alternative, also verwende ich die auch".



  • Hoppla, da ging die Post aber mal ab.
    @Bashar & icarus2
    Danke für die kurze aber einleuchtende Erklärung. Werde das entsprechend umsetzen.

    @Nathan
    Es liegt leider in der Natur der Sache, dass jeder Neueinsteiger nacheinander auf ähnliche Probleme stößt. Die Beiträge zur Funktion rand(), die ich gefunden habe waren tatsächlich schon deutlich älter, aber sei es drum. Entscheidend ist letztlich, dass man nicht immer das findet, was man sucht zumal die eigentliche Forensuche hier im Board scheinbar gar nicht funktioniert (Suche in allen Foren des Boards nach "rand" ergibt keine Beiträge entsprechen Ihren Kriterien. Die Google-Suchfunktion bringt zwar viele Treffer, aber genau darin verbirgt sich das Manko nur oberflächliche Kriterien für eine Auswahl zu finden.

    Interessant ist, dass die meisten Posts in diesem Thread sich einem anderen Thema widmen...



  • Molse schrieb:

    Interessant ist, dass die meisten Posts in diesem Thread sich einem anderen Thema widmen...

    Das gibts hier ab und zu. So entstehen nicht selten sehr interessante Diskussionen 😉

    Ist aber natürlich mühsam, wenn der Originalthread dazu gekapert wird. In solchen Fällen kannst du die Leute darauf hinweisen, möglicherweise lagert auch ein Moderator die Offtopic-Diskussion in einen separaten Thread aus.



  • Kein Problem, der dünne rote Faden ist ja noch zu sehen 🕶



  • Molse schrieb:

    @Nathan
    [...]

    Das mein ich nicht.
    Es ist absolut ok, wenn du neue Posts erstellst.
    Der Punkt ist nur der: Das ist der dritte Zufallszahlenthread seit dem 20.!
    Der DRITTE! Wieso kommen jetzt so viele davon auf einmal und davor die ganze Zeit nichts? Ähnlich bei Unicode. Darüber hab ich mich gewundert.



  • Nathan schrieb:

    Der Punkt ist nur der: Das ist der dritte Zufallszahlenthread seit dem 20.!
    Der DRITTE! Wieso kommen jetzt so viele davon auf einmal und davor die ganze Zeit nichts? Ähnlich bei Unicode. Darüber hab ich mich gewundert.

    Nathan von <a href= schrieb:

    hier">Und Nummer vier...

    3 solche Threads (wobei einer vom letzten August ist) gehen alleine auf das Konto von Chechen65.
    http://www.c-plusplus.net/forum/319066
    http://www.c-plusplus.net/forum/324530
    http://www.c-plusplus.net/forum/324668

    Wäre vielleicht langsam mal Zeit, die Dokumentation zu lesen...



  • Nathan schrieb:

    Wieso kommen jetzt so viele davon auf einmal...

    Ich dachte, das wäre gerade angesagt 😮

    Das eigentliche Problem wurde dankenswerterweise durch den passenden Tip behoben und es kann weitergehen. 👍



  • Nexus schrieb:

    3 solche Threads (wobei einer vom letzten August ist) gehen alleine auf das Konto von Chechen65.
    http://www.c-plusplus.net/forum/319066
    http://www.c-plusplus.net/forum/324530
    http://www.c-plusplus.net/forum/324668

    Wäre vielleicht langsam mal Zeit, die Dokumentation zu lesen...

    Gibt's denn ne Doku zu Chechen65, wo drinnen steht dass er merkbefreit ist? 🤡



  • hustbaer schrieb:

    Nexus schrieb:

    3 solche Threads (wobei einer vom letzten August ist) gehen alleine auf das Konto von Chechen65.
    http://www.c-plusplus.net/forum/319066
    http://www.c-plusplus.net/forum/324530
    http://www.c-plusplus.net/forum/324668

    Wäre vielleicht langsam mal Zeit, die Dokumentation zu lesen...

    Gibt's denn ne Doku zu Chechen65, wo drinnen steht dass er merkbefreit ist? 🤡

    siehe sig.


Anmelden zum Antworten