1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

randomize() spinnt!

  • Soulmerge
  • 10. Mai 2002 um 13:59
  • Unerledigt
  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 10. Mai 2002 um 13:59
    • #1

    Ich versuche gerade einen Würfelwurf zu implementieren mit einem 6-seitigen Würfel. Dazu müsste ich doch zuerst randomize() verwenden, damit rand() eine Zufallszahl liefert. Das komische ist jetzt, das die ausgabe von

    cout << (rand()%6 + 1);

    bei mir zuerst einpaar mal eine 1 liefert, dann einpaar mal eine 2, dann paar 3er, 4er, 5er und dann ein paar 6er. Die genaue Anzahl ist immer unterschiedlich, aber immer in dieser Reihenfolge!

    Weiß jemand, was ich falsch mache?

    Ich hab auch den kleinen Quellcode und das kompilierte Programm upgeloaded, würd mich freuen, wenn sich jemand kurz die Zeit nimmt, es bei sich am PC zu testen, vielleicht liegts auch an meinem Rechner (kann mir sonst nichts vorstellen...)

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • Zentor
    16
    Zentor
    Mitglied
    Reaktionen
    5
    Punkte
    2.710
    Beiträge
    506
    • 10. Mai 2002 um 14:07
    • #2

    ich kenn mich nicht so mit c++ aus aber gennerell liefert rand() doch einen Wert 0<= x <1
    wieso machst du dann rand()%6 +1 und nciht rand()*6+1 ?

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 10. Mai 2002 um 14:23
    • #3

    in c++ liefert rand() einen Wert zwischen 0 und 32767 (siehe weiter unten)

    Ich habs inzwischen mit random(6) versucht, da schauts aber auch nicht viel besser aus: die Zahlen sind nachher schon zufällig, doch kommt für eine gewisse Zeitspanne immer die gleiche Zahl, auch wenn man randomize() verwendet.

    In der Library hab ich dann die Definitioni von random(int) und rand() gefunden:

    inline int _RTLENTRY random(int __num)
    { return __num ? (int)(_lrand()%(__num)) : 0; }

    /* Maximum value returned by "rand" function */
    #define RAND_MAX 0x7FFFU

    inline void _RTLENTRY randomize(void) { srand((unsigned) time(NULL)); }

    Mich wundert, dass in der Definition von randomize ein time-Objekt übergeben wird. NULL ahnung, wieso...

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • Roli
    3
    Roli
    Mitglied
    Punkte
    65
    Beiträge
    12
    • 10. Mai 2002 um 15:04
    • #4

    hi

    also das time-Objekt ist meines wissens dafür verantwortlich, daß die generierte zahl wirklich zufällig ist.
    Würde man immer den gleichen Startwert für nen randomizer verwenden, würde man immer die gleiche zahlenfolge erzeugen.

    i hoff das stimmt so :)

    mfg
    Roli

    Sex (female) is: grep; touch; unzip; touch; gasp; finger; gasp; mount; fsck; more; yes; gasp; umount; make clean; make mrproper

    Sex (male) is: grep; touch; strip; unzip; head; mount /dev/girl -t wet; fsck; fsck; yes; yes; yes; umount /dev/girl; zip; sleep or good

  • martin
    14
    martin
    Mitglied
    Reaktionen
    69
    Punkte
    1.904
    Beiträge
    359
    • 10. Mai 2002 um 15:17
    • #5

    schau auch auf http://www.cplusplus.com/ref/cstdlib/srand.html

    die seite ist überhaupt nicht so schlecht :)

  • Zentor
    16
    Zentor
    Mitglied
    Reaktionen
    5
    Punkte
    2.710
    Beiträge
    506
    • 10. Mai 2002 um 17:26
    • #6

    ok, sorry hab gedacht das funktioniert so wie bei Java und Basic. Also auf der Seite ist ein Sample zum verwenden des rand():
    http://home1.gte.net/deleyd/random/crandom.html
    Kurz gesagt nimm einfach (double)rand()/(double)(RAND_MAX+1) um eine Zahl zw 0 und 1 zu erhalten. mit srand(seed) kann man den random number generator ein anderen seed zuweisen (seed vom Typ int). Da hilft sicher die System zeit (die Sache mit den Sekunden seit dem 1.1.1970) etwas herumtransformiert.

    p.s. es wird auf der Seite auch extra darauf hingewiesen das man nicht deine Methode verwenden soll:

    Zitat


    Note: Do NOT use

    y = rand() % M;

    as this focuses on the lower bits of rand(). For linear congruential random number generators, which rand() often is, the lower bytes are much less random than the higher bytes. In fact the lowest bit cycles between 0 and 1. Thus rand() cycles between even and odd (try it out). Be sure to do as above instead.


    mfg Zentor

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 11. Mai 2002 um 12:15
    • #7

    flyingtable07: Auf der Seite steht nur das, was das randomize() selber macht, hilft mir nicht viel, danke.

    DarkSilent: ist mir schon klar, nur frag ich mich, wiese gerade ein Time-Objekt übergeben wird (vor allem wenn wenn der Output immer für eine Zeitspanne der gleiche ist)

    Cyrill: Danke, hat auch nix genutzt, Ausgabe trotzdem genauso wie von (rand() % Zahl + 1).


    Nochmal das Problem: Mein Programm hat immer folgende Ausgabe:

    Code
    for (unsigned int i = 0; i < 1000; i++)
        cout << rand()%6+1 << " ";

    2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 und noch uur viele 2er .... 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 dann verdammt viele 5er noch 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 usw...

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 11. Mai 2002 um 12:46
    • #8

    Bis jetzt hab ich die "zufälligste" Ausgabe mit random(6)+1 erhalten, aber da wechselt die Zahl, die ausgegeben wird auch nur (ca.) sekündlich.

    Wie schauts denn bei den Leuten aus, die das zip runtergeladen haben? Da niemand was dazu gepostet hat, geh ich mal davon aus, dass es bei denen nicht anders war.

    Soweit ich das sehe, erstellt srand(Zahl) die Zufallszahlen, randomize() ist srand(time(NULL)) und man muss immer warten, bis time(NULL) etwas anderes zurückgibt, wenn man mehrere Zufallszahlen will.

    Vielleicht gibt es eine Möglichkeit, srand mit Tausendstelsekunden zu füttern? Das wäre sehr angenehm...

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 11. Mai 2002 um 13:18
    • #9

    Nochmal ich:

    Hab das Problem folgendermaßen gelöst:

    clock(): Return number of clock ticks since process start.

    Ausgabe hatte aber immer noch zuviele wiederholungen, also hab ich immer etwas verzögert:

    Code
    for (unsigned short i = 0; i < 100000; i++)
    {
        srand(clock());
        treturn = _lrand() % dice + 1;
        clock_t endwait = clock() + 0.1*CLK_TCK;
        while(clock() < endwait);
        cout << treturn << " ";
    }

    Liefert endlich *wirklich* zufällige Zahlen, zwar nur 6-8 pro Sekunde, aber das genügt, glaub ich.

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • gck
    5
    gck
    Mitglied
    Punkte
    275
    Beiträge
    55
    • 11. Mai 2002 um 13:34
    • #10

    du kannst alternativ zu

    #include < stdlib.h >

    srand(_irgendein_zufälliges_argument_);
    wuerfel = rand()%6;

    auch einfach aus /dev/random oder /dev/urandom lesen, wenn du unter Linux programmierst. Aber welchem Kernel das zur Verfügung steht bzw. obs andere Unices auch anbieten, weiß ich nicht genau, aber /dev/urandom liefert deutlich mehr (vorzeichenlose) Zufallszahlen als 6-8 pro Sekunde...

    aber wenn du als Argument für srand() was komplexeres wie ((time()%getpid())*getppid()) verwendest, solltest du eigentlich auch "echte" Zufallszahlen kriegen...

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 11. Mai 2002 um 15:17
    • #11

    Ich programmier grad in dos, aber der Obige Ausdruck hat mich auf eine andere Idee gebracht (der Ausdruck selber hat leider nicht viel geholfen, da ja der Wert des Ausdrucks ((time()%getpid())*getppid() nur von time() abhängt)

    Code
    for (unsigned int i = 0; i < 10000000; i++)
    {
        srand(clock() * i * i);
        cout << random(6) + 1 << " ";
    }

    Frag mich, wieso ich nicht gleich drafgekommen bin??!?

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • MaxAuthority
    17
    MaxAuthority
    Gewinner des Desktop-Contest 2002
    Reaktionen
    5
    Punkte
    3.165
    Beiträge
    626
    • 11. Mai 2002 um 21:34
    • #12

    wenn du unter windows programmierst ist das einfachste:

    srand(GetTickCount());
    for(int i=0; i<1000; i++)
    {
    /*kann sein dass hier ein kleines argument fehlt, hab es selbst nicht kompiliert*/
    rand()%6+1;
    }


    das wichtige ist eigentlich srand(GetTickCount()); das du aber soweit ich weiß nur einmal ausführen musst, und nicht in jedem schleifenaufruf, hatte damit noch nie probleme

    http://vimperator.org - Make Firefox behave like Vim

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 11. Mai 2002 um 22:22
    • #13

    Das ist geil!! Wenn ich winbase.h include kommt folgende Compilermeldung:


    Code
    Error E2303 C:\CPP\include\winbase.h 227: Type name expected
    Error E2139 C:\CPP\include\winbase.h 227: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 228: Type name expected
    Error E2238 C:\CPP\include\winbase.h 228: Multiple declaration for '_OVERLAPPED::ULONG_PTR'
    Error E2344 C:\CPP\include\winbase.h 227: Earlier declaration of '_OVERLAPPED::ULONG_PTR'
    Error E2139 C:\CPP\include\winbase.h 228: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 229: Type name expected
    Error E2139 C:\CPP\include\winbase.h 229: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 230: Type name expected
    Error E2238 C:\CPP\include\winbase.h 230: Multiple declaration for '_OVERLAPPED::DWORD'
    Error E2344 C:\CPP\include\winbase.h 229: Earlier declaration of '_OVERLAPPED::DWORD'
    Error E2139 C:\CPP\include\winbase.h 230: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 231: Type name expected
    Error E2139 C:\CPP\include\winbase.h 231: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 235: Type name expected
    Error E2139 C:\CPP\include\winbase.h 235: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 236: Type name expected
    Error E2139 C:\CPP\include\winbase.h 236: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 237: Type name expected
    Error E2139 C:\CPP\include\winbase.h 237: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 241: Type name expected
    Error E2139 C:\CPP\include\winbase.h 241: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 242: Type name expected
    Error E2238 C:\CPP\include\winbase.h 242: Multiple declaration for '_PROCESS_INFORMATION::HANDLE'
    Error E2344 C:\CPP\include\winbase.h 241: Earlier declaration of '_PROCESS_INFORMATION::HANDLE'
    Error E2228 C:\CPP\include\winbase.h 241: Too many error or warning messages
    *** 26 errors in Compile ***
    Alles anzeigen

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • MaxAuthority
    17
    MaxAuthority
    Gewinner des Desktop-Contest 2002
    Reaktionen
    5
    Punkte
    3.165
    Beiträge
    626
    • 11. Mai 2002 um 22:50
    • #14

    muss man eigentlich die winbase.h direkt includen?
    also wenn ich windows anwendungen schreibe, reicht normalerweise < windows.h> aus, der header included dann soweit ich weiß eh selbstständig winbase.h.

    es kann aber auch sein dass ich mich irre....

    http://vimperator.org - Make Firefox behave like Vim

  • gck
    5
    gck
    Mitglied
    Punkte
    275
    Beiträge
    55
    • 12. Mai 2002 um 11:38
    • #15
    Zitat

    Original geschrieben von Soulmerge
    Ich programmier grad in dos, aber der Obige Ausdruck hat mich auf eine andere Idee gebracht (der Ausdruck selber hat leider nicht viel geholfen, da ja der Wert des Ausdrucks ((time()%getpid())*getppid() nur von time() abhängt)

    Ok, unter DOS hast du weder die /dev/ Devices, noch Pids...
    Aber in meinem Ausdruck hängt der Wert nicht nur von der momentanen Zeit, sondern auch von der Process ID deines Programmes, sowie von der PID dessen Vater-Prozesses... solche Ausdrücke kommen in vielen GNU Programmen als "random seed" vor...

    Btw, ich verstehe deinen code nicht ganz, eigentlich solltest du mit srand(long seed) den Zufallszahlengenerator initialisieren können, sofern "seed" eine "relativ zufällige" Zahl ist, und ab dann solle rand() vorzeichenlose Integerwerte von 0 bis RAND_MAX ausspucken, jedensfalls brauchst du srand() nicht in jedem Schleifendurchgang erneut aufrufen, bringt genau "void" :)

  • Soulmerge
    7
    Soulmerge
    Mitglied
    Punkte
    405
    Beiträge
    71
    • 13. Mai 2002 um 16:02
    • #16

    AAAAAAAARRRRGH!!!

    Wie kann man nur so einen blöden Fehler machen??????!?

    Nicht nur, das srand() in jedem Schleifendurchlauf nichts bringt, sondern es bringt mich genau auf den Fehler, durch den ich diesen Thread eröffnet habe! srand() initialisiert eine Folge von Zufallszahlen, nicht nur eine!

    *ärger*

    Vielen dank für den Hinweis!

    PS: getpid() gibt Prozess-ID zurück...

    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  • Judas42
    5
    Judas42
    Mitglied
    Punkte
    195
    Beiträge
    36
    • 21. August 2002 um 22:13
    • #17

    Die Sache ist folgende: Bei einem Zufallsgenerator wird irgendeine beliebige Zahl als Startwert genommen. Bei jedem rand() wird der aktuelle Inhalt dieser Variable ausgegeben. Dann werden bestimmte Bits über irgendeinen Algorithmus miteinander verknüpft und an bestimmten Stellen in der Variable eingefügt, was einen (mehr oder weniger) zufälligen Folgewert ergibt.

    Mit randomize() wird einfach dieser Startwert gesetzt, was bei einer time-Variable mit der aktuellen Systemzeit auch "zufällig" ist. Wenn man randomize() aber mehrmals pro Sekunde aufruft, wird der Zufallsgenerator immer mit der gleichen Zahl initialisiert sodaß das darauffolgende rand() innerhalb einer Sekunde immer den gleichen Wert liefert.

    Lösung: randomize() nur ein mal aufrufen...

    EDIT: Die Variable, die den aktuellen Zufallswert und damit die Berechnungsgrundlage für den Folgewert speichert, nennt man auch "random seed" (vielleicht weil daraus der Folgewert "wächst"?)

    "The letters are Hex, of an ancient mode, but the language is that of Microsoft, which I shall not utter here."

  • jjan
    6
    jjan
    Mitglied
    Reaktionen
    8
    Punkte
    293
    Beiträge
    57
    • 22. August 2002 um 13:40
    • #18

    Hier noch die Standardantwort aus comp.lang.c zu diesem Thema ...

    http://www.eskimo.com/~scs/C-faq/q13.16.html

    [EDIT]:
    Für jeden nichttrivialen Anwendungsfall empfehle ich zur Generierung von Zufallszahlen, entweder, einen eigenen Generator zu schreiben, oder zumindest jenen aus der BOOST Bibliothek zu verwenden.

    http://www.boost.org/libs/random/index.html

    Die meisten Implementierungen von srand(), rand() und co. sind nämlich meistens miserabel.

    Eins Zwei Gras Bär Hund Vier Muh Macht Die Kuh

  • eclipsa
    1
    eclipsa
    Mitglied
    Punkte
    10
    Beiträge
    2
    • 3. Januar 2008 um 14:00
    • #19

    moin!
    also zum thema random habe ich eine frage zum folgenen code:


    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>

    // for the random number generator
    #include <cstdlib>
    #include <ctime>

    using namespace std;

    class RandomNumber {
    public:
    RandomNumber() {
    srand(time(0));
    }

    int operator() ( int n) {
    return (int)((double)n * rand()/(RAND_MAX+1.0));
    }
    };

    int
    main(int argc, char **argv)
    {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    v.push_back(6);
    v.push_back(7);
    v.push_back(8);
    cout<<v[0]<<v[1]<<v[2]<<v[3]<<v[4]<<v[5]<<v[6]<<v[7]<<v[8]<<endl;
    RandomNumber r;
    random_shuffle(v.begin(), v.end(), r);
    // copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout<<v[0]<<v[1]<<v[2]<<v[3]<<v[4]<<v[5]<<v[6]<<v[7]<<v[8]<<endl;
    return 0;
    }


    der code soll einen bitstring liefern. allerdings kommt staendig eine fehelrmedlung - weiss jemand woran das liegt?

    lg

  • eclipsa
    1
    eclipsa
    Mitglied
    Punkte
    10
    Beiträge
    2
    • 3. Januar 2008 um 14:29
    • #20

    ah, alles klar, ich hab den fehler gefunden^^
    lag nicht am programm :p das funktioniert so :p

  • Maximilian Rupp 27. Dezember 2024 um 12:04

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Rechtliches

Impressum

Datenschutzerklärung