MQL4 ve MQL5'te Rakamları () atlayarak herhangi bir sayıdan (sadece tırnak işaretleri değil) sonra ondalık basamak sayısını alma - sayfa 22

 
Andrey Khatimlianskii :

ihtiyacım yok.

Yükleyici denir, değil mi? ..

Burada, her türden her döngüden önce rastgele seçilmiş, tamamen rastgele 10.000 öğeden oluşan bir dizi verilmiştir. Her yöntemin 1000 tekrarı için toplam süre (ms).

Yerleşik ArraySort, birkaç gün önce yazdığım yöntemim (bundan önce sıralama algoritmalarıyla hiç ilgilenmiyordum) ve her şeyi yapmama rağmen kitaplığınızdaki en iyi 6 yöntem (gerisi çok daha kötüydü) oradan kaldırılan grafiklerle ilgiliydi...

 #include <Sort\GSort.mqh>
#define   ttt                 template < typename T>
#define   test(M,S,EX)        { uint mss= GetTickCount (); int nn=( int ) pow ( 10 ,M); for ( int tst= 0 ;tst<nn&&! _StopFlag ;tst++){EX;} \
                                 printf ( "%s: loops=%i ms=%u" ,S,nn, GetTickCount ()-mss);}


ttt void a_rand(T&ar[]){ for ( int i= 0 ;i< ArraySize (ar);i++)ar[i]=T( rand ()* rand ());}

ttt int TreePop(T&t[],T&ar[], int i= 0 , int b= 0 )
 {
   if (t[b+ 1 ]>= 0 )i=TreePop(t,ar,i,( int )t[b+ 1 ]);
  ar[i++]=t[b];
   if (t[b+ 2 ]>= 0 )i=TreePop(t,ar,i,( int )t[b+ 2 ]);
   return i;
 }

ttt void TreeSort(T&ar[])
 {
   int sz= ArrayRange (ar, 0 );
  T t[]; ArrayResize (t,sz* 3 ); ArrayInitialize (t,- 1 );
   for ( int i= 0 ;i< ArraySize (ar);i++){t[i* 3 ]=ar[i];
     if (!i) continue ;
     int b= 0 ;
     while ( 1 )
       if (ar[i]<=t[b])
         if (t[b+ 1 ]>= 0 )b=( int )t[b+ 1 ];
         else {t[b+ 1 ]=i* 3 ; break ;}
       else
         if (t[b+ 2 ]>= 0 )b=( int )t[b+ 2 ];
         else {t[b+ 2 ]=i* 3 ; break ;}}
  TreePop(t,ar);
 }


void OnStart (){
   double ar[];
   int N= 10000 ,k= 3 ;
   ArrayResize (ar,N);

  test(k, "ArraySort(MQL5)" ,a_rand(ar); ArraySort (ar))
  test(k, "TreeSort(AntFX)" ,a_rand(ar);TreeSort(ar))
  test(k, "Merge(GSort)" ,a_rand(ar);GMergesort(ar, 0 ,N- 1 ))
  test(k, "QTernaryLL(GSort)" ,a_rand(ar);GQSortTernaryLL(ar, 0 ,N- 1 ))
  test(k, "QSortLL(GSort)" ,a_rand(ar);GQSortTernaryLL(ar, 0 ,N- 1 ))
  test(k, "QSort(GSort)" ,a_rand(ar);GQSortTernaryLR(ar, 0 ,N- 1 ))
  test(k, "QTernaryLR(GSort)" ,a_rand(ar);GQSortTernaryLR(ar, 0 ,N- 1 ))
  test(k, "Comb(GSort)" ,a_rand(ar);GComb(ar))
}
 
Ilya Malev :

Yükleyici denir, değil mi? ..

Burada, her türden her döngüden önce rastgele seçilmiş, tamamen rastgele 10.000 öğeden oluşan bir dizi verilmiştir. Her yöntemin 1000 tekrarı için toplam süre (ms).

Yerleşik ArraySort, birkaç gün önce yazdığım yöntemim (bundan önce sıralama algoritmalarıyla hiç ilgilenmiyordum) ve her şeyi yapmama rağmen kitaplığınızdaki en iyi 6 yöntem (gerisi çok daha kötüydü) oradan kaldırılan grafiklerle ilgiliydi...

Makaledeki videoya bakılırsa, en hızlı olanlar Count, LSD ve MSD'dir.

 
Andrey Khatimlianskii :

Makaledeki videoya bakılırsa, en hızlı olanlar Count, LSD ve MSD'dir.

Bu pasajların tamamlanmasını beklemedim.

 
Alexandr Sokolov :

Ondalık noktadan sonra ondalık basamak sayısını almak gerektiğinde nadir bir durum yaşayan tek ben değilim sanırım ve Digits() işlevi yalnızca tırnak işaretleri ile çalışıyor ve ayrıca bu konuda hiçbir bilgi yok herhangi bir yerde (en azından bu yazıyı daha önce yazarken bulamadım, bu yüzden bulduğum çözümü göstermek istiyorum)?


Görünüşe göre, öz çok basit, ancak yine de bir dezavantajı var - onlardan sonra başka basamak yoksa bu işlev sıfırları tanımıyor. Örneğin, fonksiyona 0,01 sayısı verilirse 2, 0,0000 ise 0 döndürür (yani dört sıfır görmez). Bu nedenle, geliştirmelerinizde bu eksikliği göz önünde bulundurun.


MQL4'teki kod


MQL5'teki kod

MQL5'teki kodun biraz iyileştirilmesi gerekiyordu, çünkü görünüşe göre MQL5'te double türündeki değişkenler, kendisine bir tamsayı atanıp atanmadığına bakılmaksızın, sonunda otomatik olarak ,0 atanır. Ve bu nedenle fonksiyon asla 0 döndürmedi

Konu alakalıysa, işte benim versiyonum:

int kol_Z(double zzz) { // ondalık basamak sayısını hesapla

a, d dizisi;
int b, c;
a=StringFormat("%g", zzz);
b=StringFind(a,".",0);
c=StringLen(a);
if (b==-1) dönüş (0);
d=StringSubstr(a,b+1);
dönüş(StringLen(d));
}
 
NomadSoul :

Konu alakalıysa, işte benim versiyonum :

Misal:

 void OnStart ()
{
     Print (kol_Z(1.001234));
}

Sonuç: 5, ancak 6 olmalıdır

 
A100 :

Misal:

Sonuç: 5, ancak 6 olmalıdır

Ondalık basamak sayısını saymanın en kolay yolu ?". Bilgisayara, sahip olduğu mantis boyuna göre kesmesi gereken bir sayı verdikten sonra, bu sonsuz periyodik kesrin sonu nerede diye sormak nasıl mümkün olabilir?

0.0001100110011001100110011(0011) - ikili gösterimde ondalık sayı 0.1. Parantez içinde sonsuz bir kesrin periyodik kısmıdır. Peki, sonsuz sayıdan yalnızca ilk 52 anlamlı basamağı çift olarak saklanırsa, bilgisayar ne cevap vermelidir?

Ondalık gösterimdeki (0.33333...) çok kısa üçlü sayı 0.1'in ondalık noktadan sonra sonsuz sayıda anlamlı basamağa sahip olmasına kimse şaşırmaz. İkili 0.1, şans eseri sonlu sayıda basamakla ondalık 0,5'e eşittir, ortak bir bölen bulundu ve 2 ve 10 sayı sistemlerinin iki tabanında indirgendi, bu 2'dir. Her iki gösterimdeki yarının dereceleri de iyidir: 0,5 => 0,1; 0,05 => 0,01 ; 0.025 => 0.001; 0.0125 => 0.0001. Ancak kesrin paydasında 5 göründüğü anda - hepsi bu, çok sayıda önemli sayı var.

Kesirli kısımdaki anlamlı basamak sayısı, sadece sayının büyüklüğü ile değil, gösterimde kullanılan karakter sayısı ile ilgilidir.

Самый простой способ посчитать количество знаков после запятой?
Самый простой способ посчитать количество знаков после запятой?
  • 2021.01.18
  • www.mql5.com
Есть переменная. Например: double а=0.02; Нужно написать функцию, которая считала бы количество знаков после запятой...
 

1

Üç kez başlatıldı. Lider doğrudan yeleye nefes alır... Herhangi birinin ihtiyacı olursa, işlev burada - https://www.mql5.com/en/code/904 , işlevin adı SortHoareUp.

 
Dmitry Fedoseev :

Üç kez başlatıldı. Lider doğrudan yeleye nefes alır... Herhangi birinin ihtiyacı olursa, işlev burada - https://www.mql5.com/en/code/904 , işlevin adı SortHoareUp.

Ayrıca stat'den MathQuickSort () vardır. kitaplıklar (#include <Math\Stat\Math.mqh>). Çok, çok hızlı bir kütüphanenin yazdığı bir makale olduğunu hatırlıyorum)

Hızı ölçmedim, esas olarak orijinal dizinin bir dizi indeksini kaydetme yeteneği nedeniyle kullanıyorum.

 
Vladimir :

Ondalık basamak sayısını saymanın en kolay yolu ?". Bilgisayara, sahip olduğu mantis boyuna göre kesmesi gereken bir sayı verdikten sonra, bu sonsuz periyodik kesrin sonu nerede diye sormak nasıl mümkün olabilir?

0.0001100110011001100110011(0011) - ikili gösterimde ondalık sayı 0.1. Parantez içinde sonsuz bir kesrin periyodik kısmıdır. Peki, sonsuz sayıdan yalnızca ilk 52 anlamlı basamağı çift olarak saklanırsa, bilgisayar ne cevap vermelidir?

Ondalık gösterimdeki (0.33333...) çok kısa üçlü sayı 0.1'in ondalık noktadan sonra sonsuz sayıda anlamlı basamağa sahip olmasına kimse şaşırmaz. İkili 0.1, şans eseri sonlu sayıda basamakla ondalık 0,5'e eşittir, ortak bir bölen bulundu ve 2 ve 10 sayı sistemlerinin iki tabanında indirgendi, bu 2'dir. Her iki gösterimdeki yarının dereceleri de iyidir: 0,5 => 0,1; 0,05 => 0,01 ; 0.025 => 0.001; 0.0125 => 0.0001. Ancak kesrin paydasında 5 göründüğü anda - hepsi bu, çok sayıda önemli sayı var.

Kesirli kısımdaki anlamlı basamak sayısı, sadece sayının büyüklüğü ile değil, gösterimde kullanılan karakter sayısı ile ilgilidir.

Çözülecek problemin şartlarına karar vermeye başlamakta fayda var. Sayıların bilgisayardaki temsiline ilişkin teorik bir çalışmadan bahsediyorsak, bu çalışmanın amacının daha fazla açıklığa kavuşturulması gerekir.

Soru, NormalizeDouble() işlevine ikinci argüman olarak hangi tamsayı sağlanacağı ise, yanıt aynı işlev kullanılarak aranmalıdır. Bu, normalleştirilmiş sayının orijinale eşit olacağı 0 ile 8 arasındaki minimum tam sayı olacaktır. Böyle bir tam sayı yoksa, orijinal sayı yanlıştır. Burada, minimum hacim adımı için karakter sayısının hesaplandığı bir kod örneği verilmiştir.

Neden: