Zufallszahl in C

Gast #3663557
Lesenswert?

Wie ich aber wirklich eine Zufallszahl (sei es ne Pseudozufallszahl) 
erstelle, steht da aber nicht? :O

optimal möchte ich ein Zufallsbit erstellen, mit ner Wahrscheinlichkeit 
von 30%, dass es ne 0 und 70%, dass es ne 1 ist.
Gast #3663584
Lesenswert?

ahhh .. und dann überlegen wir doch mal, was time() auf einem ATMEGA 
ohne RTC liefert? Na? Da der Start-Prozess immer gleich lang dauern 
sollte wird auch time() immer den gleichen Wert liefern und damit auch 
rand()
Gast #3663600
Lesenswert?

super Markus ... 100 Punkte! Und damit sind wir wieder beim Artikel über 
die Zahlfallszahlen. Dort wird die Verwendung des ADC nicht nur für die 
Erzeugung eines Seed Wertes verwendet sondern gleich für die Erzeugung 
der Zufallszahl. Es macht ja sonst auch keinen Sinn, eine Zufallszahl 
auf einem Weg zu erzeugen, nur um dann weitere Zufallszahlen auf einem 
anderen Weg zu generieren.

Und damit sind wir wieder bei meiner Frage an den TO: für welchen Ansatz 
aus dem Beitrag hast Du Dich denn entschieden?
Gast #3663678
Lesenswert?

das Problem ist schlichtweg, dass es für alle Standard-Verfahren 
erforderlich ist, diese mit einem Zufallswert zu initialisieren - und 
genau da liegt das Problem bei Verwendung eines uC. Auf dem PC macht man 
sich das einfach und verwendet die aktuelle Uhrzeit - wie oben ja schon 
beschrieben wurde. Diese ist als Initialisierungs-Wert üblicherweise 
ausreichend zufällig. Auf einem uC sieht es (ohne RTC) aber anders aus. 
In dem Moment wo ich ihn anschalte oder resete, fängt der Uhr bei 0 an. 
Da die "Boot-Abfolge" im Idealfall aber immer gleich lang dauert, wird 
die Initialisierung aus Sicht der uC-Uhr immer zum selben Zeitpunkt 
erfolgen und ist damit nicht mehr ausreichend zufällig.

Die "Standard-Methode" dürfte im uC-Bereich tatsächlich das Auslesen 
eines rauschenden Signals mit dem ADC sein. Wenn ich das aber schon mal 
mache um einen zufälligen Initialisierungs-Wert zu erhalten, kann ich 
die gleiche Methode auch gleich verwenden um alle folgenden Zufallswerte 
zu erzeugen.

Ich will hier keinem ausreden rand() + srand() aus den 
C-Standard-Bibliotheken zu verwenden. Ich möchte nur erreichen, dass man 
sich Gedanken um die Besonderheiten der Verwendung auf dem uC macht und 
dass das halt kein PC ist.
#3663685
Lesenswert?

Na da habt ihr natürlich recht. Kenn mich mit dem  ATMega8 nicht aus.

Also meine Variante kannst du dann machen wenn du das von außen 
triggerst. Also du drückst nen Knopf und dein Prozessor gibt dir dann ne 
30:70 verteilung aus. dann bist du der zufall wann du den Knopf drückst. 
mit dem ADC klingt gut find ich wenn du die zahlen automatisch berechnen 
willst.

Aber da scheint es ja nen Thread zu geben wo das beschrieben wird
Gast #3663693
Lesenswert?

@Dussel: auch das ist eine der im oben verlinken Artikel aufgeführte 
Methode :-) erfordert aber halt eine (zufällige) Aktion von Außen, auf 
die ich im Code reagieren kann.

Um mich zu outen: wenn sich die Möglichkeit dazu bietet, ist das mein 
persönlicher Favorit ;-)
Gast #3664040
Lesenswert?

Max H. schrieb:
> Wozu wird der Zufall benötigt? Wenn ein Mensch das Gerät bedient könnte
> man aus den Zeitpunkt eines Tastendrucks Zufall generieren.

Zufall wird dafür benötigt, dass zu 70% ne 0, zu 30% ne 1 in ein 
Schieberegister geschoben wird, welche dann Led´s ansteuern, was ja aber 
unwichtig sein dürfte.
#3664062
Lesenswert?

Eine andere Variante besteht noch darin, sich den Seed im EEPROM zu 
speichern. Nach jedem Starten erhöht man den Seed, speichert ihn erneut 
im EEPROM und gibt ihn per srand an den Default-Generator weiter. So hat 
man für jeden µC-Start unterschiedliche Seed Werte.

Für ein Lauflicht ist das mit Sicherheit gut genug.

> was ja aber unwichtig sein dürfte.

Nicht ganz. Es macht schon einen Unterschied, ob die 'Zufallszahlen' ein 
paar LED blinken lassen, oder ob damit ein Geld-Spielautomat betrieben 
wird. Für ersteres reicht das simpelste vom simplen. Für letzteres aber 
nicht.
Gast #3665120
Lesenswert?

Mike schrieb:
> Zufallszahlen bei Geldspielautomaten?? Das macht doch gar keinen Sinn.
> Seit wann läuft in einem Spielautomat ein Zufallsgenerator?

Bei ZufallsSpielautomaten hehe ;)
Da schmeißt man n Euro rein, bekommt zu 10% 2 Euro und zu 90% nichts,
nein Spaß beiseite
Gast #3665217
Lesenswert?

Habe nun folgendes Programm geschrieben,
Die Funktion Test() wird natürlich im Main aufgerufen, und dann werden 
die Bits von bitarray[][] in ein SR geschoben.
Komischerweise ist die Zahl, die die Funktion ZufallsBits zurückgibt 
immer 0b00001, oder 0b00000.
alle anderen Bitkombinationen werden nie erstellt?
Wo ist mein Denkfehler..
1
char ZufallsBits(zahl)  //  liest pseudozufällig bits ein
2
{
3
  if(50 <= zahl)
4
  {
5
    return 0b00000;
6
  }
7
  else if(42 <= zahl < 50)
8
  {
9
    return 0b10000;
10
  }
11
  else if(34 <= zahl < 42)
12
  {
13
    return 0b01000;
14
  }
15
  else if(26 <= zahl < 34)
16
  {
17
    return 0b00100;
18
  }
19
  else if(18 <= zahl < 26)
20
  {
21
    return 0b00010;
22
  }
23
  else if(10 <= zahl < 18)
24
  {
25
    return 0b00001;
26
  }
27
  else
28
  {
29
    if(zahl==9)
30
    {
31
      return 0b11000;
32
    }
33
    else if(zahl==8)
34
    {
35
      return 0b10100;
36
    }
37
    else if(zahl==7)
38
    {
39
      return 0b10010;
40
    }
41
    else if(zahl==6)
42
    {
43
      return 0b10001;
44
    }
45
    else if(zahl==5)
46
    {
47
      return 0b01100;
48
    }
49
    else if(zahl==4)
50
    {
51
      return 0b01010;
52
    }
53
    else if(zahl==3)
54
    {
55
      return 0b01001;
56
    }
57
    else if(zahl==2)
58
    {
59
      return 0b00110;
60
    }
61
    else if(zahl==1)
62
    {
63
      return 0b00101;
64
    }
65
    else if(zahl==0)
66
    {
67
      return 0b00011;
68
    }
69
  }
70
}
71
void Test()
72
{
73
  unsigned char testchar=rand()%100;
74
  
75
  bitarray[0][0]=ZufallsBits(testchar);
76
}
Gast #3665259
Lesenswert?

Mike schrieb:
> Zufallszahlen bei Geldspielautomaten?? Das macht doch gar keinen Sinn.

Das ist das einzige, was "Sinn macht". Was soll der Automat denn sonst 
machen?
Siehe 
http://www.onlinecaXsinodeutsch.info/nachrichten/news_zufallsgeneratoren.php
(Das X aus dem Link entfernen, ohne hat das Forum mein Posting leider 
als Spam abgelehnt)


> Seit wann läuft in einem Spielautomat ein Zufallsgenerator?

Schon immer?
(Firma: keine) #3665314
Lesenswert?

Ich blick hier langsam die Anforderungen nicht mehr. Erst soll es eine 
Zufallszahl zwischen 0 und 20 sein. Dann soll es eine Zufallszahl 
zwischen 0 und 1 sein, mit 30%iger Wahrscheinlichkeit für 0 und 70%iger 
Wahrscheinlichkeit für 1. Das zuletzte gepostete Codebeispiel macht dann 
wieder irgendetwas Anderes, und das offensichtlich auch noch falsch
Gast #3665416
Lesenswert?

Soweit ich sehe wurden 2 Dinge bisher nicht erwähnt:

1. Die Modulo-Division (z.B. rand()%20) ist nicht optimal, wenn man 
Zufallszahlen z.B. von 0 bis 19 möchte. Grund ist, dass der Wertebereich 
der rand-Funktion kein Vielfaches von 20 ist. Es gibt daher 2 Gruppen 
von Ergebniszahlen die sich geringfügig in der Wahrscheinlichkeit 
unterscheiden.

Um die 30/70-Proportion des Threadstarters einzuhalten ist es genauer, 
einen Vergleich bei 30% von RAND_MAX zu machen als vorher %10 und dann 
>=3.


2. Wenn es um wirklich guten Zufall geht: Der AD-Wandler kann auch 
nicht-zufällige Problemchen haben. Intel hat da ein schönes Paper 
geschrieben, als sie einen Zufallszahlengenerator in die CPU eingebaut 
haben. Wenn ich mich recht errinnere schlagen sie einen Mixer vor. Das 
ist ein Entropiepuffer, aus dem ein paar Bits Zufall entnommen werden 
dürfen, der aber wieder mit echten Bits vom AD-Wandler aufgefüllt wird. 
Danach wird geschüttelt, indem man den Entropiepuffer mit einer 
Hash-Funktion auf sich selbst abbildet.

Das Paper: http://www.cryptography.com/public/pdf/IntelRNG.pdf

Grüße, Joey
#3665427
Lesenswert?

Joey, bitte machs nicht komplizerter als notwendig.

Der TO kämpft mit ganz anderen Dingen als mit qualitativ höchstwertigen 
Zufallszahlen, sieh dir sein Programm an.
Bei ihm spielt dieser kleine Fehler keine große Rolle und er wird ihn in 
seinen "Lichtshows" nie bemerken.
Gast #3665436
Lesenswert?

Fred schrieb:
> Bei Intel gehts um kryptographisch starke Zufallszahlen, hier im Thread
> nur um "Spielzeug-Zufall". Da sind diese Effekte wurscht.
>
> Für Kryptokram kann man das ADC-Samplen auch gleich sein lassen.

Ja, das ist mir schon klar. Und für sein LED-Blinken ganz ganz weit über 
das Ziel hinausgeschossen.
Ich freue mich immer, wenn mehr Background-Info angeboten wird. Es lesen 
ja auch andere mit, die vielleicht mal was anderes machen als mit LEDs 
zu blinken. Dann ist es toll wenn die wissen, dass es bei Zufallszahlen 
noch mindestens 2 Level mehr gibt.
Moderator Persönliche Seite #3665534
Lesenswert?

Joey5337 schrieb:
> Ich freue mich immer, wenn mehr Background-Info angeboten wird.

Wenn die Hintergrund-Infos aber nichts zum eigentlichen Thread-Thema 
beitragen, dann sind sie eher störend - vor allem dann, wenn sie immer 
und immer wieder eingestreut werden.

Mach doch einen eigenen Thread auf mit dem Thema:

   "Was sind gute Zufallszahlen?"

Dort wäre es wesentlich angemessener, Dein geballtes Wissen 
hinauszuschreien. Wenn ich in ein paar Jahrzehnten wissen will, wie ich 
für meinen Anwendungsfall optimale Zufallszahlen erzeugen kann, werde 
ich gewiss NICHT diesen Thread bis zum Ende durchlesen. "Ach, der will 
hier nur LEDs blinken lassen..." -> weg damit und zum nächsten Thread in 
der Suchliste.

Einem gesonderten Thread mit dem Titel

   "Was sind gute Zufallszahlen?"

würde ich als bei der Suche nach guten Zufallszahlen wesentlich mehr 
Aufmerksamkeit schenken.

Also hör bitte auf, diesen Thread hier zu verwässern, mach Deinen 
eigenen auf.
Gast #3665651
Lesenswert?

Ihr seid lustig...

ich dachte, es geht hier auch ein bischen um Spaß und niveauvolle 
Unterhaltung. Die Verweise auf xkcd, diehard-Tests und 
Geldspielautomaten fallen doch ganz klar in diese Kategorie.

Wenn es wirklich so sehr um die Verwässerung des Threads geht, wäre es 
vielleicht besser gewesen die Füße still zu halten und meinen ersten 
Beitrag einfach zu ignorieren. Jetzt haben wir schon 5 
"Meta"-Beiträge...
#3665680
Lesenswert?

putter schrieb:
> Joey5337 schrieb:
>> Jetzt haben wir schon 5
>> "Meta"-Beiträge...
>
> Und der TO hat es immer noch nicht geschafft seine LEDs blinken zu
> lassen........

er hat es ja auch noch nicht geschafft, sich mit sich selbst zu einigen, 
was eigentlich das Ziel der ganzen Sache ist. Wenn sich die 
Anforderungen dauernd ändern, was eigentlich mit diesen Zahlen passieren 
soll .....
Gast #3665685
Lesenswert?

Na, deshalb meldet er sich jetzt auch erstmal nicht, sondern wartet ab.

Vielleicht passen die sich ständig ändernden Anforderungen ja irgendwann 
mal zufällig zu seinem bereits existierenden Code.

Eine Art von "predictive coding".
Gast #3665982
Lesenswert?

Jay schrieb:
> Oliver S. schrieb:
>> Fragensteller schrieb:
>>> else if(42 <= zahl < 50)
>>
>> Du brauchst ein C-Buch.
>
> Ok, dass er die Obergrenze nochmal abprüft ist unnötig,
> aber sonst ist das doch korrekt? Warum sollte er da ein C Buch brauchen?
Soweit ich weiß, ist das Verhalten nicht definiert, aber vor Allem ist 
das wahrscheinlich nicht das, was er wollte.
Gast #3666005
Lesenswert?

Jay schrieb:
> Dussel schrieb:
>> Soweit ich weiß, ist das Verhalten nicht definiert,
>
> Was fürn Verhalten ist nicht definiert?
Ich meine das Ergebnis der Bedingung, nicht Verhalten.
Wenn die Operatoren von links nach rechts ausgeführt werden und wenn 
'true' '1' ist, ist "42<=1" '0' oder '1' und damit immer kleiner als 50. 
Allerdings bin ich nicht sicher, ob 'true' immer '1' ist.
Gast #3666019
Lesenswert?

Ein kleines Relais als Selbstschwinger (über den Öffnerkontakt) und am 
Schliesserkontakt oder über direkte, spannungsbegrenzte Auskopplung, die 
Prellimpulse pro Zeitspanne zählen. Das Ganze dann per Modulo in die 
gewünschte Range drücken... ob der Zähler dabei x-mal überläuft ist auch 
schnuppe. Die Zähl-Zeitspanne könnte man auch noch über den 
vorhergehenden Zufalls-Zählerstand zusätzlich "zufallisieren", damit es 
echt sowas von zufällig ist. ;-)
Gast #3666059
Lesenswert?

A propos Zufall bei Geldspielautomaten:

Ich hab vor zig Jahren mal als Servicetechniker für Spielgeräte 
gearbeitet. Damals waren da die überlichen 8-Bitter (Zilog und Mot) 
verbaut und die PTB hatte festgelegt, dass innerhalb einer gewissen 
Spieleanzahl (glaub 60.000) eine Auszahlqoute von mindestens 60% 
garantiert sein musste. Das wurde natürlich nur mit 
Pseudo-Zufallsgeneratoren und sequenziellem Spielplan erreicht.
Die wurden dann nach Bekantwerden des Prinzips irgendwann geknackt und 
reihenweise die Automaten geleert, indem man die hintereinander 
auftretenden Gewinnkombinationen aufgeschrieben hat und dann mittels PC 
und geknacktem Code rausfinden konnte, wo das Programm gerade stand und 
wie es weitergeht. Daraufhin wurde es von der PTB erlaubt, dass zwischen 
mehreren verschiedenen 60%-Pseudo-Zufallsgeneratoren bei jedem 
Münzeinwurf hin und her gesprungen werden durfte, so dass es 
entsprechend schwieriger wurde, den Stand der gerade aktiven 
Zufallsmaschine zu errechnen und korrekte Voraussagen zu treffen.
Es waren übrigens sowohl die Stellung der Rotationskörper, wie auch die 
Erfolgsaussichten der Zufalsleiter im Code vorherbestimmt und somit 
unabhängig vom Timing des Tastendrucks des Spielers.
#3668359
Lesenswert?

Dussel schrieb:
> Jay schrieb:
>> Dussel schrieb:
>>> Soweit ich weiß, ist das Verhalten nicht definiert,
>>
>> Was fürn Verhalten ist nicht definiert?
> Ich meine das Ergebnis der Bedingung, nicht Verhalten.

Doch, doch. Das passt schon. Das Verhalten ist exakt definiert.

> Wenn die Operatoren von links nach rechts ausgeführt werden

Diesen Satz brauchst du nicht mit 'Wenn' anfangen lassen.
Auch das ist in C exakte definiert.
Ist man sich bei der Abarbeitung von Operatoren nicht ganz sicher (was 
vorkommen kann), dann sieht man entweder in sein C Buch, oder man 
googelt nach 'Operator precedence table'. Der entnimmt man, dass die 
kleiner/größer/kleiner gleich/größer gleich Vergleichsoperatoren alle 
die gleiche Priorität haben (die höher ist als == bzw. !=) und dass sie 
von links nach rechts angewendet werden.
Somit kannst du in deinem Satz das 'wenn' ersatzlos streichen. Die Sache 
verhält sich tatsächlich und definiert genau so, wie du es beschreibst.

> und wenn
> 'true' '1' ist,

An dieser Stelle kannst du ebenfalls das 'wenn' streichen. Wenn es der 
Fall ist, dass das System einen Wahrheitswert tatsächlich generieren 
muss (wie in dem Fall, dass mit dem Ergebnis eines Vergleichs weiter 
gerechnet wird), dann gilt: logisch false wird durch 0 repräsentiert, 
logisch true wird durch 1 repräsentiert. Auch das ist genau so 
definiert, so dass du das 'wenn' in deinem Satz ersatzlos streichen 
kannst.

Der Rest deiner Ausführengen ist korrekt und auch korrekt hergeleitet. 
Lediglich die Unsicherheit in den 'wenn' kannst du streichen. Das ist 
alles genau so definiert, wie du es angenommen hast - wodurch aus dem 
'ist nicht definiert' ein 'das Verhalten ist genau definiert und verhält 
sich so, wie du es in weiterer Folge herleitest' wird.
Gast #3669172
Lesenswert?

Danke für die Aufklärung. Sicher war ich mir nicht mit der 
Auswertereihenfolge der Operatoren und ob eben 'true' 1 ist. Jede Zahl 
größer 0 (oder ungleich null?) wird ja als 'true' interpretiert, deshalb 
wusste ich nicht, ob das umgekehrt auch so gilt.
In dem gegebenen Beispiel war das Verhalten wahrscheinlich aber nicht so 
gewünscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren