Um pouco surpreendido :) Pensei em partilhar e fazer uma pergunta NÃO retórica. - página 23

 
Urain:

Vai dividir um (não necessariamente um múltiplo de 2) por outro (não necessariamente um múltiplo de 2) por um pequeno turno?

Muito bem, vou juntar o que tenho, e depois pode decidir por si próprio se precisa ou não.

Joseph Stein (1961):

gcd(n,0) = gcd(0, n) = n

gcd(n,n) = n

gcd(2n,2m) = 2gcd(n, m)

gcd(2n,2m + 1) = gcd(n, 2m + 1)

gcd(2n + 1, 2m) = gcd(2n + 1, m)

gcd(2n + 1, 2(n + k) + 1) = gcd(2(n + k) + 1, 2n + 1) = gcd(2n + 1, k)

--

Duas palestras do criador do STL Alexander Stepanov sobre Yandex

// Sobre o tema do cálculo do DNO - segunda palestra. Mas sugiro ver/ouvir os dois. Palestras fixes, homem esperto, simplesmente simpático. Sim, e útil.
Arquivos anexados:
gcd_ru.zip  365 kb
 
MetaDriver:
Se com turnos de bits, avancem. Se com a divisão modulo, não o faça.

Dividindo por sucessivas compensações

números interessantes no final do artigo:

Este algoritmo será executado no pior caso em (n-1)! iterações, onde n é a profundidade do bit divisível. Em resumo, em comparação com o algoritmo de adição sequencial, este algoritmo produz um ganho de até 9 vezes para números de 8 bits, e de até 546 vezes para números de 16 bits.

 

Portanto, eis o que tenho:

long gcd(long m, long n) 
{
  if (m<0) m=-m; 
  if (n<0) n=-n;
  if (m==0) return n; 
  if (n==0) return m;
  int d = 0;
  while ((m & 1)==0 && (n & 1)==0) { m >>= 1; n >>= 1; ++d; }
  while ((m & 1)==0) m >>= 1;
  while ((n & 1)==0) n >>= 1;
  while (m!=n)   //  while (true)  // старый вариант 
    if (m < n) 
    {
      n -= m;
      do  n >>= 1;  while ((n & 1)==0);
    } 
    else       // if (n < m) это теперь без надобности
    {
      m -= n;
      do  m >>= 1;  while ((m & 1)==0);
    } 
//    else break;  // старый вариант
    return (m <<= d);
}

parece estar a funcionar bem. por favor teste todos os buracos.

// afinou-o, é mais agradável desta forma.
Arquivos anexados:
gcd.zip  1 kb
 

Isso é estranho, não é muito rápido.

2011.04.03 22:56:59 gcdSpeedTest (EURUSD,M20) Tempo comum GreatestCommonDivisor(random(),random()) = 7656ms; // 10000000 chamadas
2011.04.03 22:56:51 gcdSpeedTest (EURUSD,M20) Tempo comum gcd(random(),random()) = 5234ms; // 10000000 chamadas

Arquivos anexados:
gcd.zip  2 kb
 
MetaDriver:

Isso é estranho, não é assim tão rápido.

2011.04.03 22:56:59 gcdSpeedTest (EURUSD,M20) Tempo comum GreatestCommonDivisor(random(),random()) = 7656ms; // 10000000 chamadas
2011.04.03 22:56:51 gcdSpeedTest (EURUSD,M20) Tempo comum gcd(random(),random()) = 5234ms; // 10000000 chamadas

Eu tenho uma diferença maior. O seu é 3-4 vezes mais rápido, mas não se esqueça que em C++ a diferença é reduzida por um factor de 2-2,5, pelo que é, honestamente, 1,5 vezes mais rápido.

void OnStart()
  {
//---
   int total=1000000;
   long x=2*3*5*7*9*11*13*17*19*21*23*29;
   long m=55*x,n=34*x;
   uint start=GetTickCount();
   for(int i=0;i<total;i++)x=gcd(m,n);      
   Print("MetaDriver gcd time=",GetTickCount()-start," x=",x);
   start=GetTickCount();
   for(int i=0;i<total;i++)x=GreatestCommonDivisor(m,n); 
   Print("Urain       GCD time=",GetTickCount()-start," x=",x);
  }
2011.04.03 22:35:41     Черновик 30 (EURUSD,M1) Urain       GCD time=1313 x=1222772020470
2011.04.03 22:35:40     Черновик 30 (EURUSD,M1) MetaDriver  gcd time= 312 x=1222772020470
 
Urain:

Eu tenho uma diferença maior. O seu é 3-4 vezes mais rápido,

mas não se esqueça que em C++ a diferença é reduzida em 2-2,5 vezes, por isso está honestamente à frente em 1,5 vezes.


E vamos ver.

Até agora, temos uma versão preliminar em mql5. Testes amigáveis, à procura de insectos.

Fi-lo como uma estrutura.

struct Rational
  {
   long              n;
   long              m;
   void ErrDZ() { Print("Rational error: zero-denominator!"); }
   void Neg() { n=-n; }
   void Norm() { long d=gcd(n,m); n/=d; m/=d; if (m<0) { n=-n; m=-m; } }
   void Assign(long a,long b) { if (b==0) { n=0; m=1; ErrDZ(); } if (b<0) { n=-a; m=-b; } else { n=a; m=b; } }
   void nAssign(long a,long b) { Assign(a,b); Norm(); }
   void Assign(long a) { Assign(a,1); }  // {n=a;m=1;}
   void Add(Rational &a) { if(m==a.m) n+=a.n; else { n*=a.m; n+=m*a.n; m*=a.m; } }
   void nAdd(Rational &a) { Add(a); Norm(); }
   void Add(long a) { n+=a*m; }
   void nAdd(long a) { Add(a); Norm(); }
   void Sub(Rational &a) { if(m==a.m) n-=a.n; else { n*=a.m; n-=m*a.n; m*=a.m; } }
   void nSub(Rational &a) { Sub(a); Norm(); }
   void Sub(long a) { n-=a*m; }
   void nSub(long a) { Sub(a); Norm(); }
   void Mul(Rational &a) { n*=a.n; m*=a.m; }
   void nMul(Rational &a) { Mul(a); Norm(); }
   void Mul(long a) { n*=a; }
   void nMul(long a) { Mul(a); Norm(); }
   void Div(Rational &a) { n*=a.m; m*=a.n; }
   void nDiv(Rational &a) { Div(a); Norm(); }
   void Div(long a) { m*=a; }
   void nDiv(long a) { Div(a); Norm(); }
   string ToString() {return "("+IntegerToString(n)+"/"+IntegerToString(m)+")";}
  };

Fiz todas as operações de duas formas - com e sem normalização. Obtive uma estrutura flexível.

Se suspeitar da possibilidade de transbordo - utilize uma versão com normalização, se não - poupe tempo (pode normalizar mais tarde, quando a espuma se tiver acumulado).

Há um teste simples em arquivo, mas é desejável testar com mais afinco.

Arquivos anexados:
 
IgorM:

obrigado pelo menos admita - corta emoticons, mas quem remove postes inteiros?

Sobre isso, Académico, Penso que é óptimo que tenha uma chamada "calculadora", mas gostaria de esclarecer se pode optimizá-la automaticamente no decurso da negociação?

Sim, é apenas um programa, se o executar, irá funcionar e dar-lhe os parâmetros ideais.
 
Uma verificação da EMA seria uma boa ideia.
 

Especialmente para este tópico, publiquei os últimos resultados dos testes MT5 (qualquer pessoa poderá repetir os testes após a próxima actualização).

Isto é o que o testador MetaTrader 5 pode fazer, e ainda mais com uma disposição completa da infra-estrutura (relatórios, gráficos, resultados, visualização).

 
Renat:

Especialmente para este tópico publiquei os últimos resultados do MT5 tester (qualquer pessoa poderá repetir os testes após a próxima actualização).

É isso que o testador MetaTrader 5 pode fazer, e mesmo com um layout completo (relatórios, gráficos, resultados, visualização).

7 símbolos, todos carrapatos, desde 2000, dois parâmetros ( variantes 200 * 200 )- 40000 passes, com uma centena de encomendas por dia para cada símbolo.

Quanto tempo é que demora?

levar 10 anos - 356 * 10 * 100 * 7 = 25 000 000 negócios

tiramos aproximadamente 10 ticks por minuto

e 10 anos - 365 * 10 * 1440 * 10 = 52 000 000 de carrapatos num só símbolo. E se estamos a ser honestos, eles estão a fazer tic-tac em cada símbolo. Portanto, devemos multiplicar honestamente por 7. E não é 10 ticks por minuto. E, por vezes, são 300.


Quanto tempo é que demora?

Razão: