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

11

20.02.2013, 13:09

..eine gute Näherung wäre womöglich sowas..

floor((rand()/RAND_MAX)*Intervallgröße+0.999f+UntererWert)

Edit: Klammern vergessen..
floor((rand()/RAND_MAX)*(Intervallgröße+0.999f)+UntererWert)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dr.hallo« (20.02.2013, 13:17)


12

20.02.2013, 14:52

Ich habe neulich erst die neuen Zufallszahlen von C++ benutzt und bin sehr zufrieden damit. Die sollte man sich wirklich angucken:

C-/C++-Quelltext

1
2
3
4
5
6
std::mt19937 mt; //Zufallszahlenquelle, es gibt diverse andere, aber MersenneTwister ist recht populär
std::uniform_real<float> gen(0.5f, 8.5f);//Unsere Verteilung, wir kriegen floats zwischen 0.5 und 8.5

//10 zahlen ausgeben
for(int i=0; i<10; ++i)
   cout << gen(mt) << endl;


Das schöne ist, dass man sowohl die Quelle frei wählen kann (z.b. auch echte Zufallszahlen) als auch den 'Generator'. So muss man sich nicht mehr darum kümmern, wie man selber Zufallszahlen im passenden Bereich bekommt, man kann etwas anderes als die Gleichverteilung wählen (dass z.B. Zahlen in der Mitte wahrscheinlicher sind) und das ganze ist Threadsicher, wenn die Zufallszahlenquelle ein lokales Objekt ist.
Lieber dumm fragen, als dumm bleiben!

Mastermind

unregistriert

13

20.02.2013, 15:18

Ich habe neulich erst die neuen Zufallszahlen von C++ benutzt und bin sehr zufrieden damit. Die sollte man sich wirklich angucken:

C-/C++-Quelltext

1
2
3
4
5
6
std::mt19937 mt; //Zufallszahlenquelle, es gibt diverse andere, aber MersenneTwister ist recht populär
std::uniform_real<float> gen(0.5f, 8.5f);//Unsere Verteilung, wir kriegen floats zwischen 0.5 und 8.5

//10 zahlen ausgeben
for(int i=0; i<10; ++i)
   cout << gen(mt) << endl;


Das schöne ist, dass man sowohl die Quelle frei wählen kann (z.b. auch echte Zufallszahlen) als auch den 'Generator'. So muss man sich nicht mehr darum kümmern, wie man selber Zufallszahlen im passenden Bereich bekommt, man kann etwas anderes als die Gleichverteilung wählen (dass z.B. Zahlen in der Mitte wahrscheinlicher sind) und das ganze ist Threadsicher, wenn die Zufallszahlenquelle ein lokales Objekt ist.


Sicherlich die beste Lösung.

14

20.02.2013, 15:42

Wer sich für die Hintergründe interessiert, hier noch ein etwas älterer Artikel:
http://magazin.c-plusplus.de/artikel/Zuf…%20den%20Zufall
Aber wie gesagt, durch die neuen Klassen sollten die meisten der da angesprochenen Probleme schon elegant behoben sein.
Lieber dumm fragen, als dumm bleiben!

15

21.02.2013, 10:29

upps..^^
"Der C++ Programmier" (das ist ein Buch) löst das Problem so..

Zitat..
//gibt eine pseudo-Zufallszahl zwischen 0 und grenze-1 zurück.
...
(size_t)((double)rand()*grenze/(RAND_MAX+1.0))

das ist aber imo nur richtig solange grenze <= (RAND_MAX+1.0).

Ich kanns nicht glauben.. sagt mir wenn ich falsch liege!

Mastermind

unregistriert

16

21.02.2013, 13:02

upps..^^
"Der C++ Programmier" (das ist ein Buch) löst das Problem so..

Zitat..
//gibt eine pseudo-Zufallszahl zwischen 0 und grenze-1 zurück.
...
(size_t)((double)rand()*grenze/(RAND_MAX+1.0))

das ist aber imo nur richtig solange grenze <= (RAND_MAX+1.0).

Ich kanns nicht glauben.. sagt mir wenn ich falsch liege!



Das ist doch genau die Formel die du oben gepostet hast nur mit 1.0 statt 0.999 und unterer Grenze von 0.

Die Einschränkung die du jetzt gerade "neu entdeckt" hast galt schon die ganze Zeit. Offensichtlich gilt (auch ohne eventuelle floating point Ungenauigkeiten):

Wenn ich mittels f(x) diskrete Punkte x mit 0 <= x < RAND_MAX auf [0,1] abbilde, ist Bild(f(x)) trotzdem nicht das ganze Intervall, sondern enthält immer noch "nur" RAND_MAX viele Elemente. Für jede Abbildung g(f(x)) muss also gelten, dass deren Bildmenge wieder nur genausoviele Elemente hat. Wenn das neue Intervall also größer ist als [0;RAND_MAX] kann schon rein prinzipiell dort nicht mehr jeder int getroffen werden.

17

21.02.2013, 15:48

Es ging mir darum:

Konkreter Grenzfall..
rmax = von rand() generierbarer Maximalwert

1.Formel
(intv+0.999) * rmax/ rmax = (intv+0.999) <- Maximum wird immer erreicht, egal wie groß intv ist.

2.Formel "C++ Programierer"
grenze * rmax / (rmax+1) = ?

bsp1.
grenze = 10
rmax = 9

10 * 9 / (9 + 1) = 9 alles noch ok: grenze-1

bsp2.
grenze = 11
rmax = 9

11 * 9 / (9 + 1) = 9.9 Fehler: grenze-1 unerreichbar

(intv* rnd / (rmax+1) != (intv+0.999) * rnd / rmax)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

18

21.02.2013, 18:54

http://www.azillionmonkeys.com/qed/random.html
http://en.wikipedia.org/wiki/Rejection_sampling


Abgesehen davon: Vergesst rand() und verwendet <random> wie Jonathan_Klein oben.

19

21.02.2013, 22:13

Ja dot, wird gemacht. Total schwieriges Thema (sieht zumindest so aus, ich kanns mir nicht alles durchlesen).

Nochmal zum "Der C++ Programmierer": Das ist in sofern kein Fehler des Autors, weil ja hier nur von Grenze (und nicht von nem inklusive-Maximum) die Rede ist, und diese wird niemals überschritten. Das erwarte ich von ner Grenze und das ist immer erfüllt, und es gehen gegenüber der 1.Formel keine Werte verloren, es trifft dann eben nur andere Werte. Also doch kein Fehler im Buch. Schade auch.

20

22.02.2013, 09:59

Das erwarte ich von ner Grenze und das ist immer erfüllt, und es gehen gegenüber der 1.Formel keine Werte verloren, es trifft dann eben nur andere Werte. Also doch kein Fehler im Buch. Schade auch.

Es geht nicht darum, ob etwas irgendwie funktioniert, oder prinzipiell richtig ist, es geht darum, was sinnvoll ist. rand() ist einfach veraltet, wer das heute noch benutzt, hat entweder keine Ahnung, wie es besser geht, oder gute Gründe es nicht zu tun (er diskutiert dann aber auch nicht hier darüber, weil er eben weiß, was er tut).

Seh es einfach so: Bücher schreiben kann jeder Depp, solange irgendein Verlag ihm dafür Geld gibt. Und die Verlage interessiert es nicht, ob ein Buch gut ist, sondern nur, ob es sich verkauft. Der ganze neue Zufallskram in C++ wurde aber von absoluten Profis entwickelt und gerade C++ ist bekannt dafür, dass im Gegensatz zu anderen Sprachen die Standardfunktionen absolut durchdacht sind und sicherlich zu dem besten gehören, das je in C++ geschrieben wurde. Wenn die etwas auf eine gewisse Art machen, dann haben die absolut immer sehr gute Gründe dafür, und es steckt nicht nur ein "wir müssen jetzt mal irgendwas neues für Zufallszahlen machen".
Lieber dumm fragen, als dumm bleiben!

Werbeanzeige