Caractéristiques du langage mql5, subtilités et techniques - page 116

 
Ilya Malev:

(fatigué) si c'était le problème, l'erreur "'k' - redéfinition ; différents modificateurs de type" apparaîtrait, mais elle n'est pas sur la capture d'écran. Donc le compilateur s'en moque et ce n'est pas le problème.

Eh bien, eh bien...

 
Alexey Navoykov:

Eh bien, eh bien...

Eh bien, essayez de le compiler vous-même. Si vous n'êtes pas trop paresseux pour écrire des messages sur ce sujet sur le forum, vous devriez être trop paresseux pour le mettre dans un éditeur et appuyer sur F7. C'est beaucoup plus rapide.

 

Un moyen rapide de calculer le logarithme binaire d'un nombre entier. 3 à 5 fois plus rapide 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
}
 
Un EA écrit en MQL5 fonctionnera-t-il sur un terminal MT4 ? J'ai lu quelque part que ça marcherait.
 
Alexey Navoykov:

Un moyen rapide de calculer le logarithme binaire d'un nombre entier. 3 à 5 fois plus rapide que MathLog.

J'utilise une fonction comme celle-ci (pur chamanisme, mais ça marche) :

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

Les deux fonctions donnent la même réponse correcte, je n'ai trouvé aucune erreur.

Il est intéressant de comparer la vitesse de fonctionnement. Ma version comporte un peu moins d'opérations de décalage et d'addition, mais il y a une multiplication à la fin. La version d'Alexey comporte un peu plus d'opérations de décalage et d'addition, mais pas de multiplication. En quoi est-il plus rapide ?

 
Les commentaires non liés à ce sujet ont été déplacés vers "Toutes les questions des débutants sur MQL4, aide et discussion sur les algorithmes et les codes".
 
Les commentaires non liés à ce sujet ont été déplacés vers "Toutes les questions des débutants sur MQL4, aide et discussion sur les algorithmes et les codes".
 
Georgiy Merts:

Ma version comporte un peu moins d'opérations de décalage et d'addition, mais pas de multiplication. La version d'Alexey comporte un peu plus d'opérations de décalage et d'addition, mais pas de multiplication. En quoi est-ce plus rapide ?

J'ai un maximum de 6 opérations de décalage et d'addition (recherche binaire).Le décalage (ulong)1<<k ne compte pas, car c'est une constante. La seule chose est que nous vérifions également l'état. Mais il y a toujours 6 opérations, plus la multiplication, plus un décalage supplémentaire et l'accès au tableau géré (c'est-à-dire la vérification de l'index). Votre version sera donc évidemment plus lente en vitesse :).

Et votre version a bien sûr l'air mystérieuse).

p.s. Je suppose que si mon code pouvait être décomposé en une chaîne de comparaisons via if-else, en se débarrassant de toutes les opérations arithmétiques, cela accélérerait énormément les choses. Mais ce serait un gros bordel de code. Si seulement on pouvait utiliser la récursion dans les macros...

 
Georgiy Merts:

Il est intéressant de comparer la vitesse.

La variante log2 est plus rapide.

#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:

L'option log2 est donc plus rapide.


Je l'ai.

Remplacer ma fonction.