Obtenir le nombre de décimales de n'importe quel nombre (pas seulement les guillemets) en contournant Digits() dans MQL4 et MQL5 - page 22

 
Andrey Khatimlianskii:

Je n'en ai pas besoin.

Vous avez une grande bouche, n'est-ce pas... ?

Voici un tableau de 10000 éléments, complètement randomisé, randomisé avant chaque cycle de tri. Temps total (ms) pour 1000 répétitions de chaque méthode.

ArraySort intégré, ma méthode écrite il y a quelques jours (avant cela, je ne faisais pas du tout d'algorithmes de tri ), et les 6 meilleures méthodes de votre bibliothèque (les autres étaient bien pires), tandis que j'ai supprimé tout ce qui concernait les graphiques...

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

Vous avez une grande bouche, n'est-ce pas... ?

Voici un tableau de 10000 éléments, complètement randomisé, randomisé avant chaque cycle de tri. Temps total (ms) pour 1000 répétitions de chaque méthode.

ArraySort intégré, ma méthode écrite il y a quelques jours (avant cela, je ne faisais pas du tout d'algorithmes de tri), et les 6 meilleures méthodes de votre bibliothèque (les autres étaient bien pires), tandis que j'ai supprimé tout ce qui concernait les graphiques...

A en juger par la vidéo de l'article, les plus rapides sont Count, LSD et MSD.

 
Andrey Khatimlianskii:

A en juger par la vidéo de l'article, les plus rapides sont Count, LSD et MSD.

Je n'ai jamais attendu que ces passes soient complétées.

 
Alexandr Sokolov:

Je pense que je ne suis pas le seul à avoir eu une situation rare où j'avais besoin d'obtenir le nombre de décimales, et la fonction Digits() ne fonctionne qu'avec des guillemets, et d'ailleurs il n'y a aucune information à ce sujet nulle part (du moins au moment d'écrire ce billet, je ne l'ai pas trouvée avant, donc je veux montrer quelle solution j'ai trouvée).


Comme il s'est avéré, l'essence de la banale simple, mais a encore un inconvénient - cette fonction ne reconnaît pas les zéros, si après eux il n'y a pas d'autres chiffres. Par exemple, la fonction renvoie 2 lorsqu'elle est suivie de 0,01, mais lorsqu'elle est suivie de 0,0000, elle renvoie 0 (c'est-à-dire qu'elle ne peut pas voir quatre zéros). Tenez donc compte de cette lacune dans vos développements.


Code en MQL4


Le code à MQL5

Le code MQL5 a dû être légèrement amélioré, car apparemment dans MQL5 les variables de type double se voient automatiquement attribuer 0 à la fin, que la variable soit un entier ou non. Et pour cette raison, la fonction n'a jamais retourné 0.

Si ce sujet est pertinent, voici mon exemple :

int kol_Z(double zzz) { // calculer le nombre de décimales

chaîne a, d ;
int b, c ;
a=StringFormat("%g", zzz) ;
b=StringFind(a,".",0) ;
c=StringLen(a) ;
si (b==-1), retour(0) ;
d=StringSubstr(a,b+1) ;
return(StringLen(d)) ;
}
 
NomadSoul:

si le sujet est pertinent, voici mon point de vue sur le sujet :

Exemple :

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

Résultat : 5 et il devrait être 6

 
A100:

Exemple :

Résultat : 5, qui devrait être 6.

le nombre de décimales?". Comment pouvez-vous, lorsque vous donnez à un ordinateur un nombre qu'il doit tronquer à la longueur de la mantisse dont il dispose, lui demander ensuite où se trouvait la fin de cette fraction périodique infinie ?

0,000110011001100110011(0011) est un nombre décimal 0,1 en représentation binaire. La partie périodique de la fraction infinie est entre parenthèses. Alors, que devrait répondre l'ordinateur, s'il ne stocke que les 52 premiers chiffres significatifs du nombre infini en double ?

Personne n'est surpris que le très court nombre ternaire 0,1 en représentation décimale (0,33333...) ait un nombre infini de chiffres significatifs après la virgule. Binaire 0,1 est égal à décimal 0,5 avec un nombre fini de chiffres par un heureux hasard, trouvé et réduit un diviseur commun dans les deux bases de notation des systèmes 2 et 10, il est 2. Les degrés de demi dans les deux représentations sont également bons : 0,5 => 0,1 ; 0,05 => 0,01 ; 0,025 => 0,001 ; 0,0125 => 0,0001. Mais dès que 5 apparaît au dénominateur d'une fraction, ça y est, il y a beaucoup de chiffres significatifs.

Le nombre de chiffres significatifs dans la partie fractionnaire est lié au nombre de caractères utilisés dans la représentation, et pas seulement à la valeur du nombre.

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

1

Je l'ai fait trois fois. Il respire dans le cou du leader... Si quelqu'un en a besoin, la fonction ici esthttps://www.mql5.com/ru/code/904, le nom de la fonction est SortHoareUp.

 
Dmitry Fedoseev:

Je l'ai fait trois fois. Il respire dans le cou du leader... Si quelqu'un a besoin, la fonction ici esthttps://www.mql5.com/ru/code/904, le nom de la fonction est SortHoareUp.

Il y a aussiMathQuickSort() de la bibliothèque (#include <Math\Stat\Math.mqh>). Je me souviens qu'il y avait un article où ils écrivaient que c'était une bibliothèque très-très rapide).

Je n'ai pas mesuré la vitesse, je l'utilise principalement parce qu'il me permet de sauvegarder un tableau d'index de tableau source.

 
Vladimir:

le nombre de décimales?". Comment peut-on donner à un ordinateur un nombre qu'il doit tronquer à la longueur de la mantisse dont il dispose, et lui demander ensuite où se trouvait la fin de cette fraction périodique infinie ?

0,000110011001100110011(0011) est un nombre décimal 0,1 en représentation binaire. La partie périodique de la fraction infinie est entre parenthèses. Alors, que devrait répondre l'ordinateur, s'il ne stocke que les 52 premiers chiffres significatifs du nombre infini en double ?

Personne n'est surpris que le très court nombre ternaire 0,1 en représentation décimale (0,33333...) ait un nombre infini de chiffres significatifs après la virgule. Binaire 0,1 est égal à décimal 0,5 avec un nombre fini de chiffres par un heureux hasard, trouvé et réduit un diviseur commun dans les deux bases de notation des systèmes 2 et 10, il est 2. Les degrés de demi dans les deux représentations sont également bons : 0,5 => 0,1 ; 0,05 => 0,01 ; 0,025 => 0,001 ; 0,0125 => 0,0001. Mais dès que 5 apparaît au dénominateur, c'est fini, il y a beaucoup de chiffres significatifs.

Le nombre de chiffres significatifs dans la partie fractionnaire est lié au nombre de chiffres utilisés dans la représentation, et pas seulement à la valeur du nombre.

Il serait bon de définir d'abord les conditions du problème à résoudre. Si nous parlons d'une sorte d'étude théorique de la représentation des nombres dans l'ordinateur, nous devons préciser davantage l'objectif de cette étude.

Si la question est de savoir quel nombre entier fournir comme deuxième argument à la fonction NormalizeDouble(), la réponse doit être recherchée dans cette fonction. Ce sera le nombre entier minimum entre 0 et 8, pour lequel le nombre normalisé sera égal au nombre source. Si aucun entier de ce type ne peut être trouvé, le numéro de la source est incorrect. Voici un exemple decode où le nombre de chiffres est compté pour l'étape du volume minimum.