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

 
Dmitry Fedoseev:

Questo: f/=0.0000001; è discutibile.

Sono d'accordo, i miliardi nel tester possono essere glitchati. per il resto è OK )

 

12'345'678'987.9991-1

12'345'678'987.9991-2

 

E questo è due volte più veloce con lo stesso risultato

int dtd2(double f)
 {
  long l=long(f/0.0000001);
  int d = 0, i = 10000000;
 
  while( d < 7 && l % i > 0 )
   {
    i /= 10;
    d ++ ;
   }

  return d ;
 }
 
Ilya Malev:

E questo è due volte più veloce con lo stesso risultato

Questa non è la velocità di cui avete bisogno qui, è fatta una volta nell'inite o da un evento GUI. La cosa principale qui è la correttezza del funzionamento. Da dove verrà la correttezza del lavoro, se si divide un problema e si scarta la parte frazionaria? Forse in qualche modo miracolosamente funziona correttamente, ma è necessario un test convincente.

 
Dmitry Fedoseev:

La velocità necessaria qui non è quella necessaria, viene fatta una volta nell'inite o da un evento GUI. La cosa principale qui è la correttezza dell'operazione. Come può funzionare correttamente se divide il doppio e scarta la parte frazionaria? Forse in qualche modo miracolosamente funziona correttamente, ma è necessario un test convincente.

Beh, se trovate dei bug (oltre a valori come 1kk+) vi sarei grato per i suggerimenti.

 
Ilya Malev:

Beh, se trovate dei bug (tranne che per valori come 1kk+) vi sarei grato per i suggerimenti.

E non li cercherò, perché non li userò. Per curiosità, come fai ad essere così sicuro che tutto sarà corretto?

 
Dmitry Fedoseev:

E non lo cercherò, perché non lo userò. Mi sto solo chiedendo come puoi essere così sicuro che tutto sarà corretto?

Ho controllato su citazioni casuali e numeri arbitrari come 0,7, 0,07, 50000000,9991 ecc. e inoltre ho fatto test comparativi di velocità. Ho solo intenzione di usare questa funzione, ma non inite, ma molto più spesso. Ma in generale, se non si balla con i tamburelli, il solito Digits è sufficiente...

 

Trovato un numero: 999999999999.9999 - dtd2() restituisce 7 e il mio è 4. Ma è un'inezia. Tutto sommato, la funzione è buona, finalmente la capisco.

 
Dmitry Fedoseev:

Trovato un numero: 999999999999.9999 - dtd2() restituisce 7 e il mio è 4. Ma è un'inezia. Tutto sommato, la funzione è buona e finalmente l'ho capita.

Beh, è quello che ho detto, ho dato io stesso un paio di questi numeri sopra.

 
#property strict

#define  test(M,EX) {uint mss=GetTickCount();int nn=(int)pow(10,M);for(int tst=0;tst<nn;tst++){EX;}printf("loops=%i ms=%u",nn,GetTickCount()-mss);}

int d(double x){
   int n;
   for(n=0;n<8;n++){
      if(x==NormalizeDouble(x,n)){
         return(n);
      }
   }
   return(n-1);
}

int dtd2(double f)
 {
  long l=long(f/0.0000001);
  int d = 0, i = 10000000;
 
  while( d < 7 && l % i > 0 )
   {
    i /= 10;
    d ++ ;
   }

  return d ;
 }
 
int dtd3(double f)
 {
  long l=long(f/0.0000001);
 
  if(l%10==0)
  if(l%100==0)
  if(l%1000==0)
  if(l%10000==0)
  if(l%100000==0)
  if(l%1000000==0)
  if(l%10000000==0)
    return 0; else
    return 1; else
    return 2; else
    return 3; else
    return 4; else
    return 5; else
    return 6; else
    return 7;
 }

void OnStart()
 {
  srand(GetTickCount());
  Print("d:");
  test(7,int k=rand()%Bars;double f=Close[k]*rand()/(rand()+1.0);d(f))
  Print("dtd2:");
  test(7,int k=rand()%Bars;double f=Close[k]*rand()/(rand()+1.0);dtd2(f))
  Print("dtd3:");
  test(7,int k=rand()%Bars;double f=Close[k]*rand()/(rand()+1.0);dtd3(f))
 }  

Test

Motivazione: