Obter o número de casas decimais de quaisquer números (não apenas citações) contornando Dígitos() em MQL4 e MQL5 - página 13

 
Dmitry Fedoseev:

Este: f/=0,0000001; é questionável.

Concordo, bilhões no testador podem estar com problemas. caso contrário está tudo bem )

 

12'345'678'987.9991-1

12'345'678'987.9991-2

 

E isto é duas vezes mais rápido com o mesmo resultado

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 isto é duas vezes mais rápido com o mesmo resultado

Esta não é a velocidade que você precisa aqui, ela é feita uma vez no inite ou por evento GUI. O principal aqui é a exatidão de operação. De onde virá a correção do trabalho, se um problema estiver sendo dividido e a parte fracionária estiver sendo descartada? Talvez de alguma forma funcione milagrosamente corretamente, mas você precisa de um teste convincente.

 
Dmitry Fedoseev:

A velocidade necessária aqui não é a velocidade necessária, ela é feita uma vez no inite ou por um evento GUI. O principal aqui é a exatidão da operação. Como pode funcionar corretamente se está dividindo o dubble e descartando a parte fracionária? Talvez de alguma forma funcione milagrosamente corretamente, mas você precisa de um teste convincente.

Bem, se você encontrar bugs (além de valores como 1kkk+), eu ficaria grato por dicas.

 
Ilya Malev:

Bem, se você encontrar bugs (exceto para valores como 1kkk+) eu ficaria grato por dicas.

E não vou procurá-los, porque não vou usá-los. Só por curiosidade, como você tem tanta confiança de que tudo estará correto?

 
Dmitry Fedoseev:

E não vou procurá-lo, porque não vou usá-lo. Só estou me perguntando como você pode ter tanta certeza de que tudo estará correto?

Verifiquei aspas aleatórias e números arbitrários como 0,7,0,07, 50000000.9991 etc., e além disso, fiz testes comparativos de velocidade. Vou apenas usar esta função, mas não de forma inativa, mas com muito mais freqüência. Mas em geral, se você não dançar com pandeiros, os Dígitos usuais são suficientes...

 

Encontrei um número: 99999999999999.9999 - dtd2() retorna 7 e o meu é 4. Mas é uma bagatela. Em suma, a função é boa, finalmente a entendo.

 
Dmitry Fedoseev:

Encontrei um número: 99999999999999.9999 - dtd2() retorna 7 e o meu é 4. Mas é uma bagatela. Em suma, a função é boa e finalmente a entendi.

Bem, foi o que eu disse, dei um par desses números acima de mim mesmo.

 
#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))
 }  

Teste

Razão: