Was braucht eine Random Klasse alles?
-
Ich brauche mehrere Zufallsgeneratoren gleichzeitig, die sich nicht gegenseitig beeinflussen. Das heisst, dass jeder Zufallsgenerator für sich immer die gleiche Zahlenfolge liefert, daher kann ich rand() nicht benutzen. Ich habe in der STL keine Klasse für einen Zufallszahlengenerator gefunden.
Ich hab mir den Algorithmus, den rand() verwendet, angeschaut und bastel mir damit jetzt 32Bit - Zufallszahlen zusammen.
Soweit, so gut, die Zufallszahlen sind schön gleichmäßig verteilt, eigentlich passt alles. Ich habe auch darauf geachtet, Betriebssystemunabhängig zu sein.
Jetzt hat mich das aber so fasziniert, dass ich noch ein paar Extras einbauen möchte, habt ihr noch irgendwelche Ideen, was man noch hinzufügen könnte?
/* Diese Klasse repräsentiert einen 32-Bit * Pseudozufallszahlengenerator. * Es können mehrere Random-Objekte * parallel verwendet werden, ohne dass sie * sich gegenseitig beeinflussen. */ class Random { public: // Initialisiert anhand der Uhrzeit. inline Random(); // Initialisiert mit dem Wert von seed. inline Random(int seed); // Liefert Werte zwischen 0 und 2^31 - 1. inline int nextInt(); inline int nextInt(int max); inline int nextInt(int max, int min); // Wert zwischen 0.0 und einschl. // 1.0 mit bis zu 8 Nachkommastellen. inline double nextDouble(); private: int currentValue; };
-
Hier poste ich noch den Code des Generators, vielleicht kann man da auch noch was verbessern:
/* Liefert die nächste Pseudo-Zufallszahl. */ inline int Random::nextInt() { currentValue = currentValue * 214013 + 2531011; const int temp1 = (currentValue >> 16) & 0x7fff; currentValue = currentValue * 214013 + 2531011; const int temp2 = (currentValue >> 16) & 0x7fff; const int result = (temp1 << 16) + temp2; assert(result >= 0); return result; }
-
Ich würd nichts mehr hinzufügen.
-
Naja, wenn du eine neue Funktion hinzufügen willst, wie wärs mit einer in der du die Grenzen der Zufallszahlen (also zwischen 5-100 eine Zufallszahl) zum Beispiel, oder wie wärs mit einer Funktion in der du das Verhältnis festlegen kannst. 3:1 zum Beispiel...
hatte mal so eine Lib programmiert in VB.net, mit lauter solchen Funktionen...
-
Für Zahlen innerhalb bestimmter Grenzen hab ich doch eine Methode.
-
btw, ich hab noch nicht ganz verstanden, wozu am Ende bei rand() nochmal das binäre UND angewendet wird. IMO bewirkt das nichts:
11000101101000110000101111011101 <- Berechnete Zahl >> 16 ------------------------------------ 00000000000000001100010110100011 00000000000000001100010110100011 <- Nach dem Shiften & 00000000000000001111111111111111 ------------------------------------ 00000000000000001100010110100011
Vielleicht ist es auch einfach schon zu spät und ich sollte ins Bett gehen.
-
Das UND bewirkt eine Begrenzung der Stellenzahl auf 15 (nicht 16, wie in deiner letzten Rechnung. 0x7fff != 0xffff)
-
*verbeug*
-
Optimizer schrieb:
Hier poste ich noch den Code des Generators, vielleicht kann man da auch noch was verbessern:
/* Liefert die nächste Pseudo-Zufallszahl. */ inline int Random::nextInt() { currentValue = currentValue * 214013 + 2531011; const int temp1 = (currentValue >> 16) & 0x7fff; currentValue = currentValue * 214013 + 2531011; const int temp2 = (currentValue >> 16) & 0x7fff; const int result = (temp1 << 16) + temp2; assert(result >= 0); return result; }
Wenn ich mich nicht verrechnet habe( d. h. 1 << 16 == 0x10000 ),
so bleibt das 16. Bit von rechts immer ungesetzt.
Man sollte besser screiben:... const int temp2 = (currentValue >> 16) & 0xffff; ...
Es sei denn, es ist beabsichtigt das (result & 0x8000) immer 0 ergibt.
-
Ich glaube, du hast Recht. Damit gibt rand() immer nur eine 15-Bit Zahl zurück. Vermutlich haben die das wegen dem Vorzeichen so gemacht?
Die shifte ich um 16 nach links und das 16te Bit bleibt ungesetzt, weil auch temp2 wieder nur ne 15-Bit Zahl ist.
Ich werde es wie von dir vorgeschlagen abändern, danke.