Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 116

 
Ilya Malev :

(yorgunlukla) bu bir sorun olsaydı, "'k' - yeniden tanımlama; farklı tür değiştiriciler" hatası çıkıyordu, ancak ekranda değil. Yani derleyici umursamıyor ve mesele bu değil.

Oh iyi...

 
Alexey Navoykov :

Oh iyi...

Peki, kendin derlemeye çalış. Eğer forumda bu konu hakkında yazı yazamayacak kadar tembel değilseniz, çok tembel olmayıp editöre sürüp F7 tuşuna basmalısınız. Çok daha hızlı.

 

Bir tamsayının ikili logaritmasını hesaplamanın hızlı bir yolu. MathLog ile hesaplamadan 3-5 kat daha hızlı çalışır.

 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
}
 
MQL5'te yazılmış bir Uzman Danışman MT4 terminalinde çalışır mı? Bir yerde işe yarayacağını okumuştum.
 
Alexey Navoykov :

Bir tamsayının ikili logaritmasını hesaplamanın hızlı bir yolu. MathLog ile hesaplamaya göre 3-5 kat daha hızlı çalışır.

Bunun gibi bir işlev kullanıyorum (saf şamanizm, ama işe yarıyor):

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

Her iki fonksiyon da doğru aynı cevabı veriyor, herhangi bir hata bulamadım.

İşin hızını karşılaştırmak ilginç. Benim versiyonumda biraz daha az kaydırma ve toplama işlemleri var ama sonunda çarpma var. Aleksey'nin versiyonunda biraz daha kaydırma ve toplama işlemleri var ama çarpma yok. Ne kadar hızlı?

 
Bu konu ile ilgili olmayan yorumlar " MQL4, yardım ve algoritmalar ve kodlar hakkında tartışma " bölümüne taşınmıştır.
 
Bu konu ile ilgili olmayan yorumlar " MQL4, yardım ve algoritmalar ve kodlar hakkında tartışma " bölümüne taşınmıştır.
 
Georgiy Merts :

Benim versiyonumda biraz daha az kaydırma ve toplama işlemleri var ama sonunda çarpma var. Aleksey'nin versiyonunda biraz daha kaydırma ve toplama işlemleri var ama çarpma yok. Ne kadar hızlı?

Kaydırma ve ekleme işlemlerim var - en fazla 6 (ikili arama). Shift (ulong)1<<k dikkate alınmaz, çünkü bu bir sabittir. Oraya giden tek şey aynı zamanda bir durum kontrolüdür. Bir koşul kontrolünüz yok, ancak her zaman 6 işlem, artı bir çarpma, artı bir vardiya daha ve ayrıca yönetilen bir diziye erişim (yani, dizini kontrol etme) vardır. Yani hız açısından, açıkçası seçeneğiniz daha yavaş olacak - büyükanneye de gitmeyin :)

Evet ve sürümünüz kesinlikle mistik görünüyor)

ps Eğer kodum if-else yoluyla bir karşılaştırmalar zincirine genişletilirse, tüm aritmetik işlemlerden kurtulursa, büyük bir hızlanma elde edebileceğinize dair bir varsayımım var. Ancak bu, kodun büyük bir ayak örtüsüdür. Makrolarda özyinelemeyi kullanabilseydiniz ...

 
Georgiy Merts :

İşin hızını karşılaştırmak ilginç.

Varyant log2 daha hızlıdır.

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

Varyant log2 daha hızlıdır.


Anladım.

Fonksiyonumu değiştiriyorum.