Ist der Wert von RAND_MAX immer (2 ^ n) -1?

8

Ich bin an C ++ interessiert, obwohl ich vermute, dass einfach die C-Standarddefinition importiert wird. Ich glaube, die Antwort ist nein für das, was der Standard sagt, aber ich bin am meisten interessiert an der Antwort in der Praxis.

Wenn RAND_MAX immer (2 ^ n) -1 ist, vereinfacht dies die Behandlung eines Problems, das kürzlich Code von MinGW GCC nach Linux GCC verschoben hat. RAND_MAX scheint größer zu sein (ich habe es nicht überprüft, aber möglicherweise gleich INT_MAX oder was auch immer das Symbol ist), so dass ein alter, naiv geschriebener RAND_MAX-ist-nicht-groß-genug-so-um-es-herum-Code fehlgeschlagen. Jetzt muss ich entscheiden, wie allgemein ich diese Bibliothek zu sein brauche, in Anbetracht der Fiddlinigkeit des Schreibens von Code, der korrekt mit der Möglichkeit des Überlaufs zurechtkommt, ohne Annahmen über z.B. die Breite eines int.

Wie auch immer, gibt es einigermaßen weit verbreitete C ++ - Compiler, die etwas anderes als (2 ^ n) -1 für RAND_MAX verwenden?

Auch korrigiere ich, dass ((RAND_MAX | (RAND_MAX & gt; & gt; 1)) == RAND_MAX) immer und nur dann wahr ist, wenn RAND_MAX gleich ((2 ^ n) -1) für irgendeine vorzeichenlose ganze Zahl n ist . Ich glaube, RAND_MAX ist technisch ein int, aber es macht keinen Sinn, einen negativen oder gebrochenen Wert zu haben, also denke ich, dass ich diese mit Sicherheit abdiskontieren kann. Bit-fiddling stört mich normalerweise nicht, aber ich denke, dass der Ausdruck falsch aussieht, und ich kann nicht herausfinden, warum.

Schließlich, obwohl ich nicht glücklich sein werde, bis ich selbst eine funktionierende Lösung habe, was sollte ich für Zufallszahlen verwenden, anstatt es selbst zu schreiben? Ich brauche Zufallszahlen im Bereich 0 & lt; = x & lt; Parameter, und ich möchte insbesondere Wahrscheinlichkeiten für alle Zahlen als gleich wahrscheinlich. Wenn Sie beispielsweise (rand ()% oberes Ende verwenden, wird eine Tendenz zu kleineren Werten angezeigt, insbesondere wenn die obere Grenze groß ist - das möchte ich vermeiden.

Gibt es dafür eine Boost- oder C ++ 0x-Sache?

BEARBEITEN

Nach etwas in dem "Related" -Bit auf der Seite der Seite gibt es tatsächlich eine Möglichkeit, Zufallszahlen mit gegebenen unteren und oberen Grenzen in Boost zu erhalten.

    
Steve314 09.02.2011, 13:48
quelle

6 Antworten

3

Ich weiß nicht, was die Garantien für RAND_MAX sind, aber Sie sollten es besser vermeiden, wenn es möglich ist, wegen der Anzahl der kaputten Implementierungen und weil es in den heutigen Anwendungen ziemlich schnell startet. Eine einheitliche Verteilung zu erhalten, wird hier beschrieben.

Ich empfehle stattdessen Boost.Random . Der Mersenne twister Generator repräsentiert einen guten Kompromiss zwischen Geschwindigkeit, Speicherverbrauch und Qualität.

    
Fred Foo 09.02.2011, 13:59
quelle
5
  • Ich kenne keine Implementierung, für die RAND_MAX nicht weniger als eine Potenz von zwei ist, aber das ist nicht durch den Standard vorgeschrieben;

  • ((RAND_MAX | (RAND_MAX & gt; & gt; 1)) == RAND_MAX) ist tatsächlich eine Möglichkeit zu testen, ob RAND_MAX um eins kleiner ist als eine Potenz von Zwei.

  • Ich benutze

    %Vor%

um so viele Zufallszahlen wie möglich von rand () zu verteilen.

    
AProgrammer 09.02.2011 13:59
quelle
4

Für Implementierungen von rand , die eine (Variante eines) Linear Congruential Generator (die meisten von ihnen) verwenden, wird RAND_MAX eine Primzahl sein, nicht unbedingt die Form 2 ^ n - 1 (eine "Mersenne Primzahl") ).

Auch ist 2 ^ 31-1 eine Primzahl, aber wenn n nicht prim ist, ist 2 ^ n - 1 nicht prim.

(In der Tat, wenn n = ab, dann 2 ^ n - 1 = (2 ^ a - 1) (1 + 2 ^ b + 2 ^ (2b) + ...))

Um 2 ^ 64 ist die einzige Mersenne-Primzahl 2 ^ 61 - 1.

Und Sie sollten lineare Kongruenzgeneratoren wirklich vermeiden, wenn Sie irgendeine halb ernsthafte Anforderung bezüglich der Erzeugung von Zufallszahlen haben. Eigentlich würde ich sagen, dass bis auf ein Tetris-Spiel rand() aus der C-Bibliothek vermieden werden sollte.

    
Alexandre C. 28.05.2011 12:16
quelle
1

In GCC (4.6) RAND_MAX = 0x7FFFFFFF (31bit) In MS Visual Studio (2012) RAND_MAX = 0x7FFF (15bit)

    
qub1n 16.09.2012 21:02
quelle
1

In Embacadero C ++ Builder sind zwei Variablen in stdlib.h definiert:

%Vor%     
Bhaskar 15.12.2012 08:10
quelle
1

In der Standard-GNU-Header-Datei stdlib.h gibt es eine Definition von RAND_MAX, die die einzige Definition in Ihrem System sein sollte:

%Vor%

Der Wert 2147483647 = 0x7fffffff ist die größte vorzeichenlose 32-Bit-Ganzzahl.

Die Rand-Funktionen, die in stdlib.h definiert sind, sind in Standard-GNU-Umgebungen mit einem Vorbehalt zuverlässig: Multi-Threading-Umgebungen (pthread) benötigen pthread-Code zum Schutz von rand (), srand () und rand_r () Aufrufe, da sie nicht reentrant sind. Eine Erklärung finden Sie auf der man-Seite für srand .

RAND_MAX sollte nirgendwo anders in Ihrem System definiert werden. Wenn Sie einen anderen Wert für RAND_MAX sehen oder eine Definition von RAND_MAX irgendwo neben stdlib.h sehen, dann muss dies eine nicht standardmäßige, nicht portable Umgebung sein. Windows ist dafür bekannt, die Standardisierung und Portabilität zu erschweren (z. B. Socket-Implementierung und APIs).

    
texadactyl 01.03.2015 18:32
quelle

Tags und Links