Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

1

19.02.2013, 15:41

Zufallsgeneratoren

Hey,

ich schreib mir gerade ein kleines Programm, bei dem ich eine Zufallszahl zwischen 7 und 12 brauche.

das ganze hab ich in eine Klasse gepackt:

.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
class Random
{
private:
    Random();
public:
    static int rnd(int low,int high);
};


.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
Random::Random()
{
    srand(static_cast<int>(std::time(NULL)));
}

int Random::rnd(int low, int high)
{
    static Random dummy;
    assert(high-low < RAND_MAX);
    return low + std::rand() % (high-low+1);
}


wenn ich nun diese Zufallszahl benötige, geschieht das Ereignis immer direkt bei der kleinen Zahl

C-/C++-Quelltext

1
2
3
4
5
6
7
if(Countdown.getElapsedTime().asSeconds() >= Random::rnd(7,10))
    {
        for(int i = 0;i <= 4;i++)
        {
            circle[i].setFillColor(sf::Color::Green);
        }
    }


weiß jemand warum er immer nach sieben Sekunden den Befehl ausführt?

lg
Moritz

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

2

19.02.2013, 15:50

Weil das, was du da gemacht hast, ein Denkfehler ist.

Guck mal was du machst, du vergleichst bei jedem(!) Durchlauf, ob die vergangene Zeit größer als deine Zufallszahl ist. Jetzt wird aber bei jedem Durchlauf eine neue Zufallszahl erstellt.
Es kann nun gut sein, dass, je nach Ausmaß deines Programms, ein paar hundert bis tausend Durchläufe pro Sekunde stattfinden. Dass nach 7 Sekunden irgendeine dieser Zufallszahlen die 7 ist, ist recht wahrscheinlich ;)
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

3

19.02.2013, 15:53

also leg dich des rand besser an den anfang also net in die schleife und ändere des dann bei jedem Reset des Programmes

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

4

19.02.2013, 15:56

Du legst es einfach so, dass in der Schleife immer mit einem, und nur einem, Wert verglichen wird, der vor dem ersten Durchlauf der Schleife festgelegt wird.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

moritz31

Treue Seele

  • »moritz31« ist der Autor dieses Themas

Beiträge: 259

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

5

19.02.2013, 16:18

okay klappt perfekt danke :D

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

6

19.02.2013, 16:59

Du brauchst dir übrigens nicht die Mühe machen, eine Klasse für Zufallszahlen zu entwerfen. Dafür ist seit C++11 gesorgt:
http://en.cppreference.com/w/cpp/numeric/random

Mastermind

unregistriert

7

19.02.2013, 21:04

Du brauchst dir übrigens nicht die Mühe machen, eine Klasse für Zufallszahlen zu entwerfen. Dafür ist seit C++11 gesorgt:
http://en.cppreference.com/w/cpp/numeric/random


EDIT: Falsche Annahme von mir, s.u.

Selbst wenn man darauf keinen Zugriff hat ist das hier gezeigte sicher keine geeignete Methode um an Zufallszahlen in einem Wertebereich zu kommen.

Ich kenne mich leider nicht genug aus um wirklich zu sagen, was hier am besten wäre aber floor((rand()/RAND_MAX)*Intervallgröße+UntererWert) sollte z.B. funktionieren.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Mastermind« (20.02.2013, 10:56)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

19.02.2013, 21:47

Was genau hast du davon, diesen Code in eine Klasse zu packen?

9

19.02.2013, 23:57

btw..
Zitat "floor((rand()/RAND_MAX)*Intervallgröße+UntererWert)"

Selbst wenn (rand()/RAND_MAX) einen float zwischen 0 und 1 ergibt, würde damit der Maximalwert des Intervalls gegenüber den anderen Werten wesentlich seltener aufgerufen werden, wenn das Ergebnis ein int sein soll.

Mastermind

unregistriert

10

20.02.2013, 10:54

btw..
Zitat "floor((rand()/RAND_MAX)*Intervallgröße+UntererWert)"

Selbst wenn (rand()/RAND_MAX) einen float zwischen 0 und 1 ergibt, würde damit der Maximalwert des Intervalls gegenüber den anderen Werten wesentlich seltener aufgerufen werden, wenn das Ergebnis ein int sein soll.



Ich hatte den Anfangspost falsch gelesen. Ich dachte er will Zahlen zwischen 7 und 12 erzeugen indem er so lange Zufallszahlen erzeugt, bis die erste in diesem Intervall liegt. Was schlechter wäre als alles andere.

Die Lösung mit dem Modulo, die er hat ist auch nicht ideal. Wenn man mal darüber nachdenkt, werden die "hinteren" Äquivalenzklassen einmal seltener "getroffen" als die vorderen, wenn RAND_MAX nicht zufällig kongruent 0 ist. Bei genügend vielen Versuchen merkt man das statistisch.

In Bezug auf deinen Einwand würde ich so pfuschen, dass "wesentlich seltener" "praktisch nie" bedeutet und daher davon ausgehen dass das Intervall nach oben offen ist.

Ich vermute dass der Fehler der Dadurch entsteht letzlich kleiner ist als der beim Modulo, kann es aber gerade nich belegen.

Wie man "richtig" Zufallszahlen aufeinem Intervall erzeugt bin ich gerade zu faul zu ergooglen, der Vorschlag war wie gesagt nur dahingerotzt weil ich dachte der Threadersteller macht etwas katastrophal schlimmeres.

Werbeanzeige