Zufallszahlengenerator. Ergebnis wirft fragen auf

Cyber

Cyber

.:DISTORTED:.
Zufallszahlengenerator. Ergebnis wirft fragen auf [solved]

Hi Leutz,

für eine Simulation habe ich einen Zufallsgenerator in C laufen, der mir zwar einwandfrei funktioniert, dennoch eine merkwürdige Eigenheit hat.
Jede generierte Zahl befindet sich (pi*daumen) innerhalb der ersten drei/viertel des maximalen Bereiches. Als Beispiel habe ich den Codeschnippsel beigefügt, der Zufallszahlen zwischen 1 und 350 erzeugt.
Als Ergebnis erhalte ich dann tatsächlich Werte zwischen 1 und bisher (nach 300 Durchläufen) 240.

Woher kommt diese Tendenz, Werte vermehrt im unteren Bereich zu bilden bzw. keine Werte im maximalen Bereich zu bilden?

Code:
int zufallszahl;
srand( (unsigned) time(NULL) );
zufallszahl = 1+(int) (350*rand()/(RAND_MAX+1.0));
 
Zuletzt bearbeitet:
Ich bekomme bei deinem Code sogar nur Einsen raus. ;)

Es ist imho besser bei der Generierung der Zufallszahl den Modulo-Operator zu benutzen, z.B. liefert
Code:
zufallszahl = rand() % 350;
eine Zahl zwischen 0 und 349.
 
Wie jetzt, Du bekommst nur einsen raus?
Warum ist es besser den Modulo zu nehmen? Ich hab irgendwo gelesen (muss ich wieder rauskramen), dass es genau anders rum besser wäre.
 
Code:
NOTES
       The  versions of rand()nd srand()n the Linux C Library
       use the same random number generator as random()nd sran*
       dom()o the lower-order bits should be as random as the
       higher-order bits.  However, on older  rand()mplementa*
       tions,  the lower-order bits are much less random than the
       higher-order bits.

       In Numerical Recipes in C: The Art of Scientific Computing
       (William  H.  Press, Brian P. Flannery, Saul A. Teukolsky,
       William T.  Vetterling;  New  York:  Cambridge  University
       Press, 1992 (2nd ed., p. 277)), the following comments are
       made:
              "If you want to generate a random integer between 1
              and 10, you should always do it by using high-order
              bits, as in

                     j=1+(int) (10.0*rand()/(RAND_MAX+1.0));

              and never by anything resembling

                     j=1+(rand() % 10);

              (which uses lower-order bits)."

       Random-number generation is a complex topic.  The  Numeri*
       cal  Recipes  in  C book (see reference above) provides an
       excellent discussion of practical random-number generation
       issues in Chapter 7 (Random Numbers).

       For  a  more theoretical discussion which also covers many
       practical issues in depth, please see  Chapter  3  (Random
       Numbers) in Donald E. Knuth's The Art of Computer Program*
       ming, volume 2 (Seminumerical Algorithms), 2nd ed.;  Read*
       ing,  Massachusetts:  Addison-Wesley  Publishing  Company,
       1981.
Quelle: man rand
 
Cybermarc schrieb:
Wie jetzt, Du bekommst nur einsen raus?
Folgender Code:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main()
{
    int i, j;

    srand((unsigned)time(NULL));
    while(1) {
        i = 1+(int) (350*rand()/(RAND_MAX+1.0));
        j = rand() % 350;
        printf("%i, %i\n", i, j);
    }

    return 0;
}
gibt
Code:
[..]
1, 147
1, 275
1, 16
1, 48
1, 275
1, 268
1, 347
1, 32
1, 143
1, 214
[..]
Bei mir kommen nur Einsen raus, weil der ganze Ausdruck (RAND_MAX+1.0) anscheinend als Integer vom Compiler aufgefasst wird und somit eine Integerdivision durchgeführt wird. Mit (350.0*rand()/(RAND_MAX+1.0)) funktioniert es fehlerfrei und ich kann dann auch solche Beobachtungen, wie du sie gemacht hast, nicht erkennen. Es sind auf den ersten Blick Zahlen von allen Bereichven vertreten.
Cybermarc schrieb:
Warum ist es besser den Modulo zu nehmen? Ich hab irgendwo gelesen (muss ich wieder rauskramen), dass es genau anders rum besser wäre.
Es ist einfacher, weniger zu schreiben und viel schneller. Fließpunktarithmetik ist immer langsamer und vor allem braucht man es in dem Fall imho gar nicht.

edit:
Ok, rtfm ist manchmal ned schlecht. ;)
 
Zuletzt bearbeitet:
@etuli:
Ja, genau das war der Text, allerdings wusste ich nicht, dass es direkt aus der man-page kam. Aber thx dafür.

@thorus:
Jo, das mit den 350 hier war mein Fehler, da ich da im prog ne double stehen hab. Die Simulation läuft jetzt mal die ganze Nacht, morgen werd ich dann sehen ob dann auch der hintere "Bereich" genutzt wurde.
 
thorus schrieb:
Es ist einfacher, weniger zu schreiben und viel schneller. Fließpunktarithmetik ist immer langsamer und vor allem braucht man es in dem Fall imho gar nicht.
Da mit modulo aber einfach abgeschnitten wird, können sich ungleichmäßige Verteilungen und statistisch abhängige Zufallszahlen ergeben.
 

Ähnliche Themen

doppelte srand() initialisierung

Zurück
Oben