Características del lenguaje mql5, sutilezas y técnicas - página 135

 
Vict:

Es usted muy considerado, gracias. Me he equivocado, no he puesto paréntesis, así que habría utilizado la función "injusta".

ZS: he hecho correcciones en el post original.

Por favor, explique por qué esta construcción es mejor que un rand()%max trivial.

ZS: Entiendo lo que quieres decir.
Entonces, ¿qué pasa si max>32767? Su función es de tipo uint, pero genera el mismo máximo que rand(), es decir, 32767

Es mejor que uses algo como

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

Es usted muy considerado, gracias. Me equivoqué, no puse paréntesis, así que usaría la función "injusta".

ZS: he hecho correcciones en el post original.

¿Te das cuenta de que si alguien quiere usar tu función honesta y escribir get_rand(10), funcionará 3276 veces más lento que rand()%10

 
Nikolai Semko:

Entonces, ¿qué pasa si max>32767? Después de todo, su función es de tipo uint, pero genera el máximo que rand(), es decir, 32767.

es mejor usar algo como

Y MathRand() devuelve int, ¿qué pasa si alguien espera un número con seis ceros de él? Contando con algún nivel de público. Aquí, usted mismo sabe cómo obtener > 32767.

A menudo escriben rand()%3 sin pensarlo dos veces y luego ven mi mensaje y se dan cuenta de que cambiarán las probabilidades.

¿Te das cuenta de que si alguien quiere usar tu función honesta y escribir get_rand(10), funcionará 3276 veces más lento que rand()%10

Pues sí, muy lento, para un ciclo de un millón de llamadas un callback while ocurrirá unas 300 veces. Si tus programas consisten en for() desnudos en los que get_rand() está jugueteando, eso sería crítico, supongo.

¿Y te das cuenta de que el programador del sistema operativo está ocupando mucho tiempo de la CPU y ralentizando la ejecución de forma desproporcionada con respecto a rand()? Si tienes tanta prisa, necesitas algún tipo de dosis.

 
Vict:

Y MathRand() devuelve int, ¿qué pasa si alguien espera un número con seis ceros de él? Cuento con un cierto nivel de público. Aquí, usted mismo sabe cómo obtener > 32767.

A menudo escriben rand()%3 sin pensarlo dos veces y luego ven mi mensaje y se dan cuenta de que habrá un cambio de probabilidad.

Pues sí, muy lento, para un ciclo de un millón de llamadas un callback while ocurrirá unas 300 veces. Si tus programas consisten en for() desnudos en los que get_rand() está jugueteando, eso sería crítico, supongo.

¿Y te das cuenta de que el programador del sistema operativo está ocupando mucho tiempo de la CPU y ralentizando la ejecución de forma desproporcionada con rand()? Si tienes tanta prisa, necesitas algún tipo de dosis.

La velocidad de las funciones es fundamental en la optimización. Y no se trata del programador y del DOS.
 
Vict:

Y MathRand() devuelve int, ¿qué pasa si alguien espera un número con seis ceros de él? Cuento con un cierto nivel de público. Aquí, usted mismo sabe cómo obtener > 32767.

A menudo escriben rand()%3 sin pensar y ven mi mensaje y se dan cuenta de que cambiará las probabilidades.

Pues sí, muy lento, para un ciclo de un millón de llamadas un callback while ocurrirá unas 300 veces. Si tus programas consisten en for() desnudos en los que get_rand() está jugueteando, eso sería crítico, supongo.

¿Y te das cuenta de que el programador del sistema operativo está ocupando mucho tiempo de la CPU y ralentizando la ejecución de forma desproporcionada con respecto a rand()? Si tienes tanta prisa, necesitas algún tipo de dosis.

No tengas miedo de admitir tus errores, no hay nada que asuste o humille. Todos cometemos errores. Es normal.
Es mucho más fácil y más útil en términos de percepción de la comunidad decir: "Sí, me equivoqué. Gracias". en lugar de tratar de poner excusas.

Esto funciona mucho más rápido y de forma más universal:

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;
  }

Puedes acelerarlo si lo recodificas de ulong a uint, si no necesitas números grandes (necesitas 3 rand() en lugar de cinco).

 
Nikolai Semko:

No tengas miedo de admitir tus errores: no hay nada de miedo ni de humillación en ello. Todos cometemos errores. No pasa nada.
Es más fácil y más útil para la comunidad decir: "Sí, me equivoqué. Gracias". En lugar de intentar justificarse.

Al fin y al cabo, funciona mucho más rápido y de forma más universal:

También se puede acelerar recodificando de ulong a uint, si no se necesitan números grandes (3 rand() en lugar de cinco).

Entonces, ¿no le confunde la injusticia de su aplicación (en términos de velocidad, por cierto, será mucho más lenta)? Como quieras.

Zy: deshonestidad - generando números de diferente rango con diferentes probabilidades.
 
Vict:

Entonces, ¿no te confunde lo injusto de tu aplicación (que será mucho más lenta en términos de velocidad, por cierto)? Como quieras.

Zy: la deshonestidad está generando diferentes números de rango con diferentes probabilidades.
¿Hablas en serio?
 
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++.
 
¿Así que estás dispuesto a prender fuego a un billete de 100 dólares para encontrar una moneda de diez centavos enrollada bajo la cama?
 
Nikolai Semko:
¿Así que estás dispuesto a prender fuego a un billete de 100 dólares para encontrar una moneda de diez centavos enrollada bajo la cama?

No hay que subestimar el papel de las probabilidades. En las iteraciones multimillonarias estos "centavos rodados" te costarán cifras bastante tangibles. Además, tu código es obviamente irracional en rangos pequeños (hacer constantemente cinco llamadas a rand() es exactamente el "quemar la nota")

Hace seis meses ya se discutió este tema en el foro, yo sugerí esta opción:

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

¿Cómo obtener un número aleatorio en un rango de profundidad N?

Alexey Navoykov, 2018.12.31 01:25

Mi último código resultó ser incorrecto. Me he complicado demasiado con los dígitos. Aquí está la variante correcta y más concisa al mismo tiempo:

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
}
Razón de la queja: