Forum: Mikrocontroller und Digitale Elektronik AVR und Zufallszahlen


von Jens-Erwin (Gast)


Lesenswert?

Hallo,

möchte Zufallszahlen einsetzen - aber wie.


DA-Wandler brauche ich - kann ich nicht verwenden.


Bisher habe ich Zufallszahlen im SRAM "gesammelt" (z.B. beim
Verändern des AD-Wertes Timer auslesen)

Bin über alle Erfahrungen damit dankbar.

Gruß Jens-Erwin

von Hartmut Gröger (Gast)


Lesenswert?

Zufallszahlen können diskret(mit schaltkreisen) erzeugt werden,indem
man ein Schieberegister benutzt, bei dem bestimmte Bits über
Exor-verknüpfung auf den Eingang zurückgefuhrt werden.Das lässt sich
auch Softwaremäßig realisieren.
Eine andere Möglichkeit ist,ein analoges Rauschsignal zu erzeugen,und
dieses über Komperatoren in den MC einzulesen.

von Jens-Erwin (Gast)


Lesenswert?

Ja danke --- Schieberegister geht,

habe die Frage ins richtige Forum gestellt, nicht hierher - Verzeiung

von nobody0 (Gast)


Lesenswert?

Für das Problem gibt's auch in den C-FAQs einen portablen Standard
Random Number Generator:

// portable random number generator of Park and Miller; best C-FAQs
version
#   define PMRAND_MIN 1         // Min. output
#   define PMRAND_MAX 2147483647        // Max. output
#   define a 48271
#   define m 2147483647
#   define q (m / a)
#   define r (m % a)

static long int seed = 1;

// initialisation, e. g. PMrand_seed((long int)time(NULL))
void
PMrand_seed (long int j)
{
  seed = j;
  return;
}

// seed==0-tolerant version
signed long int
PMrand ()
{
  signed long int hi = seed / q;
  signed long int lo = seed % q;
  signed long int test = a  lo - r  hi;
  if (test > 0)
    seed = test;
  else
    seed = test + m;
  return seed;
}

#   undef a
#   undef m
#   undef q
#   undef r


Die Qualität dieser Zufallszahlen ist gut; beispielsweise ist die
Ausgabe modulo 2 NICHT gleich 0, 1, 0, 1 ....

Zum Initialisieren wird meist time genommen, also:

PMrand_seed((long int)time(NULL));

Falls man time nicht zur Verfügung hat, dann muß man die Systemzeit in
Sekunden nehmen; jedenfalls etwas, was sich ständig ändert und
praktisch nicht (exakt) vorhersagbar ist.
Weil time nur als seed dient, also nicht direkt im Zufallswert steckt,
ist diese Lösung einfach und zuverlässig.

Wenn's um reinen echten Zufall geht, wird's normalerweise zu
aufwendig (www.true-random.com).

von nobody0 (Gast)


Lesenswert?

Korrektur: Das Maximum war um 1 zu groß angegeben; richtig ist:

#   define PMRAND_MAX 2147483646        // Max. output

von Andi (Gast)


Lesenswert?

Wieso?
War doch korrekt?
Höchste positive Zahl mit 32 Bit ohne Vorzeichen (minus) ist doch
01111111111111111111111111111111 (7FFFFFFF).
In Dezimal 2147483647.
Oder nicht?

Gruß
Andi

von nobody0 (Gast)


Lesenswert?

Also ich habe das aus den C-FAQs genommen; ich habe es nicht komplett
nachgerechnet.
Und in den C-FAQs steht ein RAND_MAX von 2147483646 zu dem obigen
Generator.
Der Rückgabewert liegt im Intervall [1,2147483646].
Dass der Rückgabewert mindestens 1 ist, ist leicht zu sehen, aber das
Maximum 2147483646 ist, sehe ich nicht, aber das kann man ja
nachrechnen. Dafür bin ich zu faul und ich vertraue darauf, dass das
stimmt; in Zweifel würde ich einfach mal einige Millarden Werte
ausgeben lassen und Minimum, Maximum sowie Periode experimentell
bestimmen, denn letztlich entscheidend ist das, was hinten rauskommt
und es ist schneller programmiert als gerechnet.

von Sebastian B. (m0nkey)


Lesenswert?

Tut mir leid so einen alten Thread wieder haraus zu holen, aber ich hab 
da ein paar fragen zu dem zufallsgenerator, der hier beschrieben wird.

1. Welche Seite ist deine Quelle, wenn ich nach C-FAQs und Park and 
Miller google finde ich nichts, zumindest nciht diesen Code hier

2. Stimmt diese Zeile vom Code?
1
signed long int test = a  lo - r  hi;

Gruß Sebastian

von wieder (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Sebastian Baier schrieb:

> 2. Stimmt diese Zeile vom Code?
1
signed long int test = a  lo - r  hi;
2
>

Da müssen klarerweise * dazwischen.
Die sind von der Forensoftware ausgefiltert worden und als Formatierung 
für Fettdruck umgesetzt worden.

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
Noch kein Account? Hier anmelden.