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

 
Ilya Malev:

(cansado) si ese fuera el problema, aparecería el error "'k' - redefinición; diferentes modificadores de tipo", pero no está en la captura de pantalla. Así que el compilador no se preocupa y no es el problema.

Bueno, bueno...

 
Alexey Navoykov:

Bueno, bueno...

Bueno, intente compilarlo usted mismo. Si no te da pereza escribir mensajes sobre este tema en el foro, te debería dar pereza ponerlo en un editor y pulsar F7. Es mucho más rápido.

 

Forma rápida de calcular el logaritmo binario de un entero. Funciona de 3 a 5 veces más rápido que MathLog.

int log2(ulong n)
{
  if (n==0) return -1;
  
  #define  S(k) if (n >= (ulong(1)<<k)) { i += k;  n >>= k; }
  
  int i=0;  S(32);  S(16);  S(8);  S(4);  S(2);  S(1);  return i;
  
  #undef  S
}
 
¿Funcionará un EA escrito en MQL5 en un terminal MT4? He leído en algún sitio que funcionará.
 
Alexey Navoykov:

Forma rápida de calcular el logaritmo binario de un entero. Funciona de 3 a 5 veces más rápido que MathLog.

Yo uso una función como esta (puro chamanismo, pero funciona):

static const uint ulLogTable[64] = 
{
0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63 
};


uint _FastLog2(ulong ulInput)
{
   ulInput |= ulInput >> 1;
   ulInput |= ulInput >> 2;
   ulInput |= ulInput >> 4;
   ulInput |= ulInput >> 8;
   ulInput |= ulInput >> 16;
   ulInput |= ulInput >> 32;
  
   return(ulLogTable[(uint)((ulInput * 0x03f6eaf2cd271461) >> 58)]);
};

Ambas funciones dan la misma respuesta correcta, no he encontrado ningún error.

Es interesante comparar la velocidad de funcionamiento. Mi versión tiene un poco menos de operaciones de desplazamiento y suma, pero hay multiplicación al final. La versión de Alexey tiene un poco más de operaciones de desplazamiento y suma, pero no hay multiplicación. ¿Cómo es más rápido?

 
Los comentarios no relacionados con este tema han sido trasladados a "Cualquier pregunta de los novatos en MQL4, ayuda y discusión sobre algoritmos y códigos".
 
Los comentarios no relacionados con este tema han sido trasladados a "Cualquier pregunta de los novatos en MQL4, ayuda y discusión sobre algoritmos y códigos".
 
Georgiy Merts:

Mi versión tiene algo menos de operaciones de desplazamiento y suma, pero no de multiplicación. La versión de Alexey tiene algo más de operaciones de desplazamiento y suma, pero no de multiplicación. ¿Cómo es más rápido?

Tengo un máximo de 6 operaciones de desplazamiento y suma (búsqueda binaria). Eldesplazamiento (ulong)1<<k no cuenta, porque es una constante. Lo único es que también comprobamos el estado. Pero siempre hay 6 operaciones, más la multiplicación, más un desplazamiento más y el acceso al array gestionado (es decir, la comprobación del índice). Así que su versión será obviamente más lenta por la velocidad :).

Y tu versión, por supuesto, parece misteriosa).

p.d. Tengo la suposición de que si mi código pudiera desenvolverse en una cadena de comparaciones mediante if-else, deshaciéndose de todas las operaciones aritméticas, aceleraría enormemente las cosas. Pero sería un gran lío de código. Si sólo se pudiera usar la recursión en las macros...

 
Georgiy Merts:

Es interesante comparar la velocidad de funcionamiento.

La variante log2 es más rápida.

#property strict
#define    test(M,S,EX)        {uint mss=GetTickCount();uint nn=(uint)pow(10,M);for(uint t12=0;t12<nn;t12++){EX;} \
                                printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}

int log2(ulong n){
  if (n==0) return -1;
  #define  S(k) if (n >= (ulong(1)<<k)) { i += k;  n >>= k; }
  int i=0;  S(32);  S(16);  S(8);  S(4);  S(2);  S(1);  return i;
  #undef  S}


static const uint ulLogTable[64] = {
0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63 };

uint _FastLog2(ulong ulInput){
   ulInput |= ulInput >> 1;
   ulInput |= ulInput >> 2;
   ulInput |= ulInput >> 4;
   ulInput |= ulInput >> 8;
   ulInput |= ulInput >> 16;
   ulInput |= ulInput >> 32;  
   return(ulLogTable[(uint)((ulInput * 0x03f6eaf2cd271461) >> 58)]);};

void OnStart(){
  srand(GetTickCount());
  ulong n,n1;
  test(8,"MathLog",n=rand()*rand();n1=ulong(MathLog(n)/MathLog(2)))
  test(8,"log2",n=rand()*rand();n1=log2(n);)
  test(8,"_FastLog2",n=rand()*rand();n1=_FastLog2(n))}


 
Ilya Malev:

Así que la opción log2 es más rápida.


Lo tengo.

Reemplazar mi función.