Características da linguagem mql5, subtilezas e técnicas - página 135

 
Vict:

É muito atencioso, obrigado. Cometi um erro, não coloquei parênteses, por isso teria usado a função "injusta".

ZS: fez correcções ao posto original.

Explique por favor porque é que esta construção é melhor do que um rand()%max trivial.

ZS: Estou a ver o que quer dizer.
Bem, então - e se max>32767? A sua função é do tipo uint, mas gera o mesmo máximo que rand(), i.e. 32767

É melhor usar 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:

É muito atencioso, obrigado. Cometi um erro, não coloquei parênteses, por isso usaria a função "injusta".

ZS: fez correcções ao posto original.

Percebe que se alguém quiser usar a sua função honesta e escrever get_rand(10), funcionará 3276 vezes mais lentamente do que rand()%10

 
Nikolai Semko:

Bem, então - e se max>32767? Afinal, a sua função é do tipo uint, mas gera o máximo que rand(), i.e. 32767.

é melhor usar algo como

E MathRand() retorna int, e se alguém espera um número com seis zeros dele? Contando com algum nível de público. Aqui, você mesmo sabe como obter > 32767.

Eles apenas escrevem frequentemente rand()%3 sem pensar duas vezes e depois vêem a minha mensagem e apercebem-se de que isso irá mudar as probabilidades.

Percebe que se alguém quiser usar a sua função honesta e escrever get_rand(10), funcionará 3276 vezes mais lentamente do que rand()%10

Bem, sim, muito lento, para um ciclo de um milhão de chamadas de retorno enquanto acontece cerca de 300 vezes. Se os seus programas consistirem em bare for() where get_rand() is fidgeting, isso seria crítico, suponho eu.

E apercebe-se de que o programador os está a ocupar muito tempo de CPU e a atrasar a execução de forma proporcional ao rand()? Se está com tanta pressa, precisa de algum tipo de dose.

 
Vict:

E MathRand() retorna int, e se alguém espera um número com seis zeros dele? Estou a contar com um certo nível de público. Aqui, você mesmo sabe como obter > 32767.

Escrevem frequentemente rand()%3 sem pensar duas vezes e depois vêem a minha mensagem e percebem que haverá uma mudança de probabilidade.

Bem, sim, muito lento, para um ciclo de um milhão de chamadas de retorno enquanto acontece cerca de 300 vezes. Se os seus programas consistirem em bare for() where get_rand() is fidgeting, isso seria crítico, suponho eu.

E apercebe-se de que o programador os está a ocupar muito tempo de CPU e a atrasar a execução de forma proporcional ao rand()? Se está com tanta pressa, precisa de algum tipo de dose.

A velocidade das funções é fundamental para a optimização. E não se trata do programador e do DOS.
 
Vict:

E MathRand() retorna int, e se alguém espera um número com seis zeros dele? Estou a contar com um certo nível de público. Aqui, você mesmo sabe como obter > 32767.

Eles apenas escrevem frequentemente rand()%3 sem pensar e ver a minha mensagem e apercebem-se de que isso irá mudar as probabilidades.

Bem, sim, muito lento, para um ciclo de um milhão de chamadas de retorno enquanto acontece cerca de 300 vezes. Se os seus programas consistirem em bare for() where get_rand() is fidgeting, isso seria crítico, suponho eu.

E apercebe-se que o programador os está a ocupar muito tempo de CPU e a atrasar desproporcionadamente a execução para rand()? Se está com tanta pressa, precisa de algum tipo de dose.

Não tenha medo de admitir os seus erros, não há nada de assustador ou humilhante nisso. Todos nós cometemos erros. É normal.
É muito mais fácil e mais útil em termos de percepção da comunidade dizer: "Sim, eu estava errado. Obrigado". em vez de tentar arranjar desculpas.

Isto funciona muito mais rapidamente e de forma mais flexível:

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

Pode acelerá-lo se o recodificar de ulong para uint, se não precisar de grandes números (precisa de 3 rand() em vez de cinco).

 
Nikolai Semko:

Não tenha medo de admitir os seus erros - não há nada de assustador e humilhante nisso. Todos nós cometemos erros. Está tudo bem.
É muito mais fácil e mais útil para a comunidade dizer: "Sim, eu estava errado. Obrigado". Em vez de tentar justificar-se a si próprio.

Afinal, esta opção funciona muito mais rapidamente e de forma mais universal:

Também pode ser acelerada recodificando de ulong para uint, se não precisar de grandes números (3 rand() em vez de cinco).

Então não se confunde com a injustiça da sua implementação (em termos de rapidez, a propósito, será muito mais lenta)? Como queira.

Zy: desonestidade - gerando diferentes números de gama com diferentes probabilidades.
 
Vict:

Então não está confuso com a injustiça da sua implementação (a propósito, será muito mais lento em termos de velocidade)? Como queira.

Zy: a desonestidade está a gerar diferentes números de gama com diferentes probabilidades.
Está a falar a sério?
 
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++.
 
Então está disposto a pegar fogo a uma nota de 100 dólares para encontrar uma moeda de dez cêntimos enrolada debaixo da cama?
 
Nikolai Semko:
Então está disposto a pegar fogo a uma nota de 100 dólares para encontrar uma moeda de dez cêntimos enrolada debaixo da cama?

Não deve subestimar o papel das probabilidades. Em iterações multimilionárias, estes "tostões enrolados" custar-lhe-ão números bastante tangíveis. Além disso, o seu código é obviamente irracional em pequenos intervalos (fazer constantemente cinco chamadas para rand() é exactamente o "queimar a nota")

Há seis meses atrás este tópico já tinha sido discutido no fórum, eu sugeri esta opção:

Fórum sobre comércio, sistemas comerciais automatizados e teste de estratégias comerciais

Como obter um número aleatório na gama N de profundidade ?

Alexey Navoykov, 2018.12.31 01:25

O meu último código revelou-se incorrecto. Causei demasiados problemas com os dígitos. Aqui está a variante certa e mais concisa ao mesmo tempo:

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
}