+1 oder -1 zufällig wählen



  • rand4speed schrieb:

    (rand()&2)-1
    

    Schöne Lösung, zumal sie auch noch ohne Division (modulo) auskommt (auch wenn wohl jeder halbwegs intelligente Compiler bei einem "%2" wohl keine DIV-Instruktion erzeugt).

    rand4speed schrieb:

    Wie schaut denn der neue random header aus? Bin recht noch ein ziemlicher Neuling was das angeht, google spuckt alles mögliche aus..

    http://en.cppreference.com/w/cpp/header/random

    Für die hier genannten Lösungen sähe das dann mit dem neuen random-header etwa so aus:

    #include <random>
    ...
    std::minstd_rand generator(std::random_device());
    std::uniform_int_distribution<int> verteilung(0, 1);
    ...
    int zufallszahl = verteilung(generator) * 2 - 1;
    

    Die Verteilung (hier Gleichverteilung - "uniform distribution") ermöglicht es ziemlich einfach einen Wertebereich anzugeben, in dem die Zufallszahlen liegen sollen. Ich würde diese Variante bevorzugen, da die Modulo-Lösung den Nachteil hat, dass die Zufallszahlen nicht für alle Wertebereiche genau gleichverteilt sind (In diesem speziellen Fall allerdings schon).

    Finnegan



  • Einfach so:

    rand()%2? 1 : -1
    

    Wir sind hier schließlich nicht beim obfuscated code contest.


  • Mod

    Das ternäre if ist doch einer der Grundpfeiler des IOCCC. 🙂



  • Hier noch eine Möglichkeit:

    "\xFF\x01"[rand()%2]
    

  • Mod

    ioccc schrieb:

    Hier noch eine Möglichkeit:

    "\xFF\x01"[rand()%2]
    

    Und dann mit -fsigned-char kompilieren?



  • Zugegeben,

    std::array<int,2>{-1,1}[rand()%2]
    

    ist standardkonformer (da es weder von der Signedness, noch der 8-Bittigkeit und Overfloweigenschaft von char abhängt).



  • Und Indices in Arrays zu generieren ist auch imo der beste Weg um komplexere Zahlenverteilungen zu erhalten.



  • Falls %2 auf der Plattform zu langsam oder nicht verfügbar ist, kann man auch diese Lösung verwenden:

    for (;;)
    {
    	int r = -23 + std::rand();
    	if (std::labs(r) == 1)
    	{
    		return r;
    	}
    }
    

    Wenn die Zufallszahl sich nicht so oft ändern muss, geht auch das:

    std::ptrdiff_t randomness = reinterpret_cast<std::intptr_t>(&std::rand);
    return (randomness < 0) ? -1 : 1;
    

    Oder der Klassiker für maximale Effizienz:

    int uninitialized;
    return (uninitialized < 0) ? -1 : 1;
    

  • Mod

    Warum du labs verwendest (und nicht abs ) ist mir schleierhaft. Und warum ptrdiff_t für randomness ?

    Oder der Klassiker für maximale Effizienz:

    UB. Außerdem nicht zufällig wenn die Stackframes sich überschneiden.

    Ich befürchte eine Deface-Attacke auf TyRoXx Account, daher fühle ich mich verpflichtet moderationstechnische Maßnahmen zu ergreifen und Account bis auf weiteres zu sperren. 🤡



  • Vielen Dank euch Allen, hat mir sehr geholfen!



  • Arcoth schrieb:

    Und warum ptrdiff_t für randomness ?

    Oh, ich habe das mal korrigiert:

    std::intptr_t randomness = reinterpret_cast<std::ptrdiff_t>(&std::rand);
    return (randomness < 0) ? -1 : 1;
    

    Arcoth schrieb:

    Oder der Klassiker für maximale Effizienz:

    UB. Außerdem nicht zufällig wenn die Stackframes sich überschneiden.

    Kein Problem, einfach mit -O0 übersetzen.


Anmelden zum Antworten