Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 135

 
Vict:

Sie sind sehr rücksichtsvoll, vielen Dank. Ich habe einen Fehler gemacht, ich habe keine Klammern gesetzt, dann hätte ich die Funktion "unfair" verwendet.

ZS: Korrekturen am ursprünglichen Beitrag vorgenommen.

Bitte erklären Sie, warum diese Konstruktion besser ist als ein triviales rand()%max.

ZS: Ich verstehe, was Sie meinen.
Und was ist, wenn max>32767? Ihre Funktion ist vom Typ uint, erzeugt aber den gleichen Höchstwert wie rand(), d.h. 32767

Verwenden Sie besser etwas wie

ulong RandULong(ulong max=ULONG_MAX) {return(((ulong)rand()<<60)|((ulong)rand()<<45)|((ulong)rand()<<30)|((ulong)rand()<<15)|(ulong)rand())%max;}
 
Vict:

Sie sind sehr rücksichtsvoll, vielen Dank. Ich habe einen Fehler gemacht, ich habe keine Klammern gesetzt, also würde ich die Funktion "unfair" verwenden.

ZS: Korrekturen am ursprünglichen Beitrag vorgenommen.

Ist Ihnen klar, dass, wenn jemand Ihre ehrliche Funktion verwenden und get_rand(10) schreiben möchte, diese 3276 Mal langsamer arbeiten wird als rand()%10

 
Nikolai Semko:

Und was ist, wenn max>32767? Schließlich ist Ihre Funktion vom Typ uint, erzeugt aber maximal den Wert von rand(), d.h. 32767.

verwenden Sie besser etwas wie

Und MathRand() gibt int zurück, was, wenn jemand eine Zahl mit sechs Nullen erwartet? Ich rechne mit einem gewissen Grad an Öffentlichkeit. Hier wissen Sie selbst, wie Sie > 32767 bekommen.

Oft schreiben sie einfach rand()%3, ohne zweimal darüber nachzudenken, und dann sehen sie meine Nachricht und merken, dass sich dadurch die Wahrscheinlichkeiten verschieben.

Ist Ihnen klar, dass, wenn jemand Ihre ehrliche Funktion verwenden will und get_rand(10) schreibt, es 3276 Mal langsamer funktioniert als rand()%10

Nun ja, sehr langsam, bei einem Zyklus von einer Million Aufrufen wird ein Rückruf etwa 300 Mal erfolgen. Wenn Ihre Programme aus bloßen for() bestehen, in denen get_rand() herumfuchtelt, wäre das kritisch, denke ich.

Und ist Ihnen klar, dass der Betriebssystem-Scheduler eine Menge CPU-Zeit in Anspruch nimmt und die Ausführung von rand() überproportional verlangsamt? Wenn man es so eilig hat, braucht man eine Art Dosierung.

 
Vict:

Und MathRand() gibt int zurück, was, wenn jemand eine Zahl mit sechs Nullen erwartet? Ich rechne mit einem gewissen Grad an Öffentlichkeit. Hier wissen Sie selbst, wie Sie > 32767 bekommen.

Oft schreiben sie einfach rand()%3, ohne zweimal darüber nachzudenken, und dann sehen sie meine Nachricht und erkennen, dass es eine Wahrscheinlichkeitsverschiebung geben wird.

Nun ja, sehr langsam, bei einem Zyklus von einer Million Aufrufen wird ein Rückruf etwa 300 Mal erfolgen. Wenn Ihre Programme aus bloßen for() bestehen, in denen get_rand() herumfuchtelt, wäre das kritisch, denke ich.

Und ist Ihnen klar, dass der Betriebssystem-Scheduler eine Menge CPU-Zeit in Anspruch nimmt und die Ausführung von rand() überproportional verlangsamt? Wenn man es so eilig hat, braucht man eine Art Dosierung.

Bei der Optimierung ist die Geschwindigkeit der Funktionen entscheidend. Und es geht nicht um den Scheduler und DOS.
 
Vict:

Und MathRand() gibt int zurück, was, wenn jemand eine Zahl mit sechs Nullen erwartet? Ich rechne mit einem gewissen Grad an Öffentlichkeit. Hier wissen Sie selbst, wie Sie > 32767 bekommen.

Sie schreiben einfach oft rand()%3, ohne nachzudenken, und sehen meine Nachricht und erkennen, dass sich dadurch die Wahrscheinlichkeiten verschieben.

Nun ja, sehr langsam, bei einem Zyklus von einer Million Aufrufen wird ein Rückruf etwa 300 Mal erfolgen. Wenn Ihre Programme aus bloßen for() bestehen, in denen get_rand() herumfuchtelt, wäre das kritisch, denke ich.

Und ist Ihnen klar, dass der Betriebssystem-Scheduler eine Menge CPU-Zeit in Anspruch nimmt und die Ausführung von rand() überproportional verlangsamt? Wenn man es so eilig hat, braucht man eine Art Dosierung.

Scheuen Sie sich nicht, Ihre Fehler zuzugeben, das hat nichts Beängstigendes oder Demütigendes an sich. Wir alle machen Fehler. Das ist normal.
Es ist viel einfacher und nützlicher für die Wahrnehmung in der Gemeinschaft, zu sagen: "Ja, ich habe mich geirrt. Ich danke Ihnen." anstatt zu versuchen, Ausreden zu finden.

Das funktioniert viel schneller und flexibler:

ulong randUlong(ulong max=ULONG_MAX)
  {
   static bool f=true;
   if(f) {f=false; srand(GetTickCount());}
   return(((ulong)rand()<<60)|((ulong)rand()<<45)|((ulong)rand()<<30)|((ulong)rand()<<15)|(ulong)rand())%max;
  }

Sie können es beschleunigen, wenn Sie es von ulong zu uint umkodieren, wenn Sie keine großen Zahlen brauchen (Sie brauchen 3 rand() statt fünf).

 
Nikolai Semko:

Scheuen Sie sich nicht, Ihre Fehler einzugestehen - das hat nichts Beängstigendes und Demütigendes an sich. Wir alle machen Fehler. Das ist in Ordnung.
Es ist viel einfacher und hilfreicher für die Gemeinschaft, zu sagen: "Ja, ich habe mich geirrt. Ich danke Ihnen." Anstatt zu versuchen, sich zu rechtfertigen.

Schließlich funktioniert diese Option viel schneller und universeller:

Es kann auch durch Umkodierung von ulong zu uint beschleunigt werden, wenn Sie keine großen Zahlen benötigen (3 rand() statt fünf).

Sie sind also nicht verwirrt durch die Ungerechtigkeit Ihrer Umsetzung (in Bezug auf die Geschwindigkeit wird sie übrigens viel langsamer sein)? Wie Sie wollen.

Zy: Unehrlichkeit - Generierung unterschiedlicher Zahlenbereiche mit unterschiedlichen Wahrscheinlichkeiten.
 
Vict:

Sie sind also nicht verwirrt über die Ungerechtigkeit Ihrer Umsetzung (die übrigens viel langsamer sein wird)? Wie Sie wollen.

Zy: Unehrlichkeit erzeugt unterschiedliche Zahlenbereiche mit unterschiedlichen Wahrscheinlichkeiten.
Ist das Ihr Ernst?
 
Why do people say there is modulo bias when using a random number generator?
Why do people say there is modulo bias when using a random number generator?
  • 2012.06.11
  • user1413793user1413793 5,32651933
  • stackoverflow.com
I have seen this question asked a lot but never seen a true concrete answer to it. So I am going to post one here which will hopefully help people understand why exactly there is "modulo bias" when using a random number generator, like in C++.
 
Sie sind also bereit, einen 100-Dollar-Schein anzuzünden, um einen unter das Bett gerollten Zehner zu finden?
 
Nikolai Semko:
Sie sind also bereit, einen 100-Dollar-Schein in Brand zu setzen, um einen unter dem Bett verstaubten Groschen zu finden?

Sie sollten die Rolle der Wahrscheinlichkeiten nicht unterschätzen. Bei mehreren Millionen Iterationen kosten Sie diese "gerollten Pennys" ganz handfeste Zahlen. Außerdem ist Ihr Code bei kleinen Bereichen offensichtlich irrational (fünfmaliges Aufrufen von rand() ist genau das "Verbrennen der Note")

Vor sechs Monaten wurde dieses Thema bereits im Forum diskutiert, und ich habe diese Option vorgeschlagen:

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wie erhält man eine Zufallszahl im Bereich der Tiefe N?

Alexey Navoykov, 2018.12.31 01:25

Mein letzter Code erwies sich als falsch. Ich habe mir zu viel Mühe mit Ziffern gemacht. Hier ist die richtige Variante und gleichzeitig prägnanter:

ulong RandomLong(ulong range)
{
 #define _MAXRND(range, rnd_range)  ((rnd_range) - ((rnd_range)-range)%range - 1) 
 #define _RND (ulong)rand()
  ulong rnd, max, const bit=1;
  if (range <= bit<<15) { if (!range) return0;  max=_MAXRND(range, 1<<15);  while((rnd=_RND) > max);  return rnd%range; }
  if (range <= bit<<30) { max=_MAXRND(range, bit<<30);  while((rnd=(_RND | _RND<<15)) > max);  return rnd%range; }
  if (range <= bit<<45) { max=_MAXRND(range, bit<<45);  while((rnd=(_RND | _RND<<15 | _RND<<30)) > max);  return rnd%range;  }
  if (range <= bit<<60) { max=_MAXRND(range, bit<<60);  while((rnd=(_RND | _RND<<15 | _RND<<30 | _RND<<45)) > max);  return rnd%range; }
                  else  { max=_MAXRND(range, bit<<64);  while((rnd=(_RND | _RND<<15 | _RND<<30 | _RND<<45 | _RND<<60)) > max);  return rnd%range; }
 #undef _RND               
 #undef _MAXRND
}