Hallo, ich soll in C eine zufallszahl generieren, die einer Zeit von 0 bis 1 Sekunde entspricht. Mit der rand Funktion bekomme ich auf jedenfall eine Zufallszahl heraus. Kriege diese jedoch nicht unter eine Sekunde??? Ist es auch richtig wenn ich iin der srand Funktion einen Wert mit einem Timer hochzählen lasse, dass ich damit den Startwert beeinflusse und somit die Zufallszahl? Danke im vorraus
Warum kriegst du die Zahl nicht unter 1 Sekunde? rand() liefert dir eine Zahl im Bereich 0 bis RAND_MAX. Die Division ist schon erfunden.
> Ist es auch richtig wenn ich iin der srand Funktion einen Wert > mit einem Timer hochzählen lasse, dass ich damit den Startwert > beeinflusse und somit die Zufallszahl? Nein. Das ist nicht richtig. Du sollst mittels srand() den Zufallszahlengenerator einmal initialisieren und dann den 'Seed' in Ruhe lassen. Nur so hast du überhaupt eine Chance dass die Zahlen die rand() liefert auch nur irgendwas ähnliches wie Zufallszahlen sind. Im Rechner gibt es keine Zufallszahlen (ausser man benutzt thermisches Rauschen an Dioden oder so. Ist aber alles extrem aufwändig). Daher behilft man sich so: Es gibt eine Formel bei der man die letzte Zufallszahl hineinstopft und dafür die nächste Zufallszahl herauskriegt. Bei der nächsten Anforderung geht dieses alte Ergebnis wieder in die Formel ein und man kriegt das nächste Ergebnis. Die Kunst besteht nun darin, eine Formel zu finden, so dass die generierten Zahlen die statistischen Eigenschaften von Zufallszahlen haben. Dazu musst du aber die Formel arbeiten lassen. Wenn die mittels srand() da immer wieder eingreifst, zerstörst du die Statistik und deine Zahlen sind Mist.
> Im Rechner gibt es keine Zufallszahlen
Du meinst zwar im Prinzip das richtige, aber die Aussage ist doch etwas
zu allgemein.
Man sollte vielleicht besser sagen, dass es in den meisten
(einfacheren) Rechnern keine Zufallszahlen gibt.
Aber schon bei einem einfach PC, gibt es Quellen für taugliche
Zufallszahlen.
Da wäre z.B. das Timing von empfangen Netzwerkpakete beim
Internet-Surfen. Oder das Timing von Festplattenzugriffen oder das
Timing von Tastatur- und Mausereignissen etc.
Jeder diese Vorgänge bietet ein paar Bits oder auch weniger
"Zufallsinformation". Zwar nur sehr wenig, aber immerhin.
Aber richtig ist, dass Library-Funktionen wie rand() etc. diese
Zufallsquellen nicht benutzen, sondern eine Algorithmus, wie Du ihn
beschrieben hast, verwenden.
Deshalb nennen sich solche Funktionen auch Pseudo-Zufallsgenerator.
Echte Zufallzahlen gibt es unter vernüftigen Betriebssystemen z.B.
unter /dev/random.
Bau dir einen alternativen Zufallsgenerator. Für µC und Co. zum Beispiel hab ich mal einen Roulette-Zufallsgenerator auf einem Shift-XOR-Register aufgebaut : ;**************************************** WAIT TIMER RANDOM: ; Zufallszahl beschreiben ( RANDOM ) cli RANDOM_AGAIN: ldi TEMP2,0 call RANDOM_BIT lsl TEMP2 call RANDOM_BIT lsl TEMP2 call RANDOM_BIT lsl TEMP2 call RANDOM_BIT lsl TEMP2 call RANDOM_BIT lsl TEMP2 call RANDOM_BIT cpi TEMP2,37 brsh RANDOM_AGAIN mov RANDOM,TEMP2 sei ret RANDOM_BIT: ; erzeugt zufälliges Bit -> TEMP2.0 ldi ZH,0x35 ldi ZL,00 bclr 0 andi TEMP2,0b11111110; Result := 0 sbrc SR1,0 bset 0 brcc RB_ROLL ori TEMP2,0b00000001; Result := 1 lpm TEMP1,Z+ eor SR1,TEMP1 lpm TEMP1,Z+ eor SR2,TEMP1 lpm TEMP1,Z+ eor SR3,TEMP1 lpm TEMP1,Z+ eor SR4,TEMP1 lpm TEMP1,Z+ eor SR5,TEMP1 lpm TEMP1,Z+ eor SR6,TEMP1 lpm TEMP1,Z+ eor SR7,TEMP1 lpm TEMP1,Z+ eor SR8,TEMP1 RB_ROLL: ror SR8 ror SR7 ror SR6 ror SR5 ror SR4 ror SR3 ror SR2 ror SR1 ret Auf der Addresse "0x3500" liegt ein Maskendwort : .db 0b01010110,0b00000000 ; L,ML .db 0b00000000,0b10000000 ; MH,H .db 0b00100110,0b00000000 ; L,ML .db 0b00000000,0b00001000 ; MH,H Random_Bit erzeugt ein Zufallsbit, Random eine Zufallszahl. Als Ausgang wird ein 64bit Register (SR1-8) verwendet, also recht unwahrscheinlich, dass da viel Murks passiert. Als Startwert kannst du SR1-SR8 nach dem Power-On des µCs mit Werten aus dem SRAM befüllen Diese sind dann physikalisch schon absolut zufällig. Diese Technik ist relativ schnell, speichersparend und ziemlich Zufallssicher. Je kleiner das Register (SR1-8), desto schneller arbeitet der Algo. Allerdings leidet der Zufall dann darunter. Für ein 32bit-Register einfach nur die ersten 4 Maskenbytes verwenden.
>Als Startwert kannst du SR1-SR8 nach dem
Power-On des µCs mit Werten aus dem SRAM befüllen Diese sind dann
physikalisch schon absolut zufällig.
Ich denke das stimmt so nicht. Ich hab z.B. festgestellt das sich die
Werte besonders bei nicht allzulangen off-zeiten kaum bis nicht ändern.
Sicher, es ist besser als nix, aber es gibt andere Methoden:
1. Offener ADC eingang mit einem Stück leiterbahn dran. Fängt alle
möglichen Störungen ein. Alternativ kann man noch ne Diode mit hoher
Rauschspannung oder ähnliches anschließen.
2. Wenn es Interaktion mit dem User gibt: Schnell laufenden Timer
verwenden und die Zeit zwischen zwei Tastendrücken messen.
3. Vor den Ausschalten die letzte Pseudozufallszahl im EEPROM
speichern. Ist zwar nicht mehr wirklich zufällig, aber man weiß
wenigstens sicher, dass es irgendwo los geht, wo sinnvolle daten
stehen. Im SRAM stehen mit etwas Pech lauter 0en. Diese Methode eignet
sich auch gut für 2. als Ergänzung um die Zeit bis zum ersten
Tastendruck zu überbrücken.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.