Ottenere il numero di posizioni decimali di qualsiasi numero (non solo le virgolette) bypassando Digits() in MQL4 e MQL5 - pagina 22

 
Andrey Khatimlianskii:

Non ne ho bisogno.

Hai la bocca larga, vero...?

Ecco un array di 10000 elementi, completamente randomizzato, randomizzato prima di ogni ciclo di ordinamento. Tempo totale (ms) per 1000 ripetizioni di ogni metodo.

ArraySort incorporato, il mio metodo scritto un paio di giorni fa (prima non mi occupavo affatto di algoritmi di ordinamento ), e 6 metodi migliori dalla tua libreria (il resto era molto peggio), mentre ho rimosso da lì tutto ciò che riguarda la grafica...

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

Hai la bocca larga, vero...?

Ecco un array di 10000 elementi, completamente randomizzato, randomizzato prima di ogni ciclo di ordinamento. Tempo totale (ms) per 1000 ripetizioni di ogni metodo.

ArraySort incorporato, il mio metodo scritto un paio di giorni fa (prima non facevo affatto algoritmi di ordinamento), e 6 metodi migliori dalla tua libreria (il resto era molto peggio), mentre ho rimosso da lì tutto ciò che riguarda la grafica...

A giudicare dal video dell'articolo, i più veloci sono Count, LSD e MSD.

 
Andrey Khatimlianskii:

A giudicare dal video nell'articolo, i più veloci sono Count, LSD e MSD.

Non ho mai aspettato che questi passaggi fossero completati.

 
Alexandr Sokolov:

Penso di non essere l'unico che ha avuto una rara situazione in cui avevo bisogno di ottenere il numero di cifre decimali, e la funzione Digits() funziona solo con le virgolette, e inoltre non ci sono informazioni al riguardo da nessuna parte (almeno al momento di scrivere questo post non le ho trovate prima, quindi voglio mostrare quale soluzione ho trovato).


Come si è scoperto, l'essenza del semplice banale, ma ha ancora un inconveniente - questa funzione non riconosce gli zeri, se dopo di loro non ci sono altre cifre. Per esempio, la funzione restituirà 2 se seguita da 0,01, ma se seguita da 0,0000 restituirà 0 (cioè non può vedere quattro zeri). Quindi, considerate questa lacuna nei vostri sviluppi.


Codice in MQL4


Il codice di MQL5

Il codice MQL5 ha dovuto essere leggermente migliorato, perché apparentemente in MQL5 alle variabili di tipo doppio viene automaticamente assegnato 0 alla fine, non importa se la variabile è un intero o no. E per questo motivo, la funzione non ha mai restituito 0.

Se questo argomento è rilevante, ecco il mio esempio:

int kol_Z(double zzz) { // calcola il numero di cifre decimali

stringa a, d;
int b, c;
a=StringFormat("%g", zzz);
b=StringFind(a,".",0);
c=StringLen(a);
se (b==-1) return(0);
d=StringSubstr(a,b+1);
return(StringLen(d));
}
 
NomadSoul:

se l'argomento è rilevante, ecco la mia opinione in merito:

Esempio:

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

Risultato: 5 e dovrebbe essere 6

 
A100:

Esempio:

Risultato: 5, che dovrebbe essere 6.

il numero di cifre decimali? Come si può, quando si dà a un computer un numero che deve troncare alla lunghezza della mantissa che ha, poi chiedergli dov'era la fine di quella frazione periodica infinita?

0,000110011001100110011(0011) è un numero decimale 0,1 in rappresentazione binaria. La parte periodica della frazione infinita è tra parentesi. Allora, cosa dovrebbe rispondere il computer, se memorizza solo le prime 52 cifre significative del numero infinito in doppio?

Nessuno si sorprende che il brevissimo numero ternario 0,1 in rappresentazione decimale (0,33333...) abbia un numero infinito di cifre significative dopo la virgola. Binario 0,1 è uguale a decimale 0,5 con un numero finito di cifre per caso felice, trovato e ridotto un divisore comune nelle due basi di sistemi di notazione 2 e 10, è 2. I gradi di metà in entrambe le rappresentazioni sono anche buoni: 0,5 => 0,1; 0,05 => 0,01 ; 0,025 => 0,001 ; 0,0125 => 0,0001. Ma appena il 5 appare nel denominatore di una frazione, ecco che ci sono molte cifre significative.

Il numero di cifre significative nella parte frazionaria è legato al numero di caratteri usati nella rappresentazione, non solo al valore del numero.

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

1

L'ho eseguito tre volte. E' con il fiato sul collo del leader... Se qualcuno ne ha bisogno, la funzione qui èhttps://www.mql5.com/ru/code/904, il nome della funzione è SortHoareUp.

 
Dmitry Fedoseev:

L'ho eseguito tre volte. E' con il fiato sul collo del leader... Se qualcuno ha bisogno, la funzione qui èhttps://www.mql5.com/ru/code/904, il nome della funzione è SortHoareUp.

C'è ancheMathQuickSort() dalla libreria (#include <Math\Stat\Math.mqh>). Ricordo che c'era un articolo in cui si scriveva che è una biblioteca molto-molto veloce).

Non ho misurato la velocità, lo uso principalmente perché mi permette di salvare array di indici di array di origine.

 
Vladimir:

il numero di cifre decimali? Come si può dare a un computer un numero che deve troncare alla lunghezza della mantissa che ha, e poi chiedergli dov'era la fine di quella frazione periodica infinita?

0,000110011001100110011(0011) è un numero decimale 0,1 in rappresentazione binaria. La parte periodica della frazione infinita è tra parentesi. Allora, cosa dovrebbe rispondere il computer, se memorizza solo le prime 52 cifre significative del numero infinito in doppio?

Nessuno si sorprende che il brevissimo numero ternario 0,1 in rappresentazione decimale (0,33333...) abbia un numero infinito di cifre significative dopo la virgola. Binario 0,1 è uguale a decimale 0,5 con un numero finito di cifre per caso felice, trovato e ridotto un divisore comune nelle due basi di sistemi di notazione 2 e 10, è 2. I gradi di metà in entrambe le rappresentazioni sono anche buoni: 0,5 => 0,1; 0,05 => 0,01 ; 0,025 => 0,001 ; 0,0125 => 0,0001. Ma appena il 5 appare nel denominatore di una frazione, ecco che ci sono un sacco di cifre significative.

Il numero di cifre significative nella parte frazionaria è legato al numero di cifre usate nella rappresentazione, e non solo al valore del numero.

Sarebbe una buona idea definire prima le condizioni del problema da risolvere. Se stiamo parlando di una sorta di studio teorico della rappresentazione dei numeri nel computer, dobbiamo chiarire ulteriormente lo scopo di questo studio.

Se la domanda riguarda quale intero fornire come secondo argomento alla funzione NormalizeDouble(), dovreste usare la stessa funzione per trovare la risposta. Questo sarà il minimo intero tra 0 e 8, per il quale il numero normalizzato sarà uguale al numero sorgente. Se non è possibile trovare un tale numero intero, il numero di origine non è corretto. Ecco un esempio dicodice in cui si conta il numero di cifre per il passo di volume minimo.

Motivazione: