Obtener el número de decimales de cualquier número (no sólo las comillas) evitando Digits() en MQL4 y MQL5 - página 13

 
Dmitry Fedoseev:

Este: f/=0,0000001; es cuestionable.

Estoy de acuerdo, los miles de millones en el probador puede ser glitchy. de lo contrario está bien )

 

12'345'678'987.9991-1

12'345'678'987.9991-2

 

Y esto es el doble de rápido con el mismo 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:

Y esto es el doble de rápido con el mismo resultado

Esto no es la velocidad que necesita aquí, se hace una vez en el inite o por evento GUI. Lo principal aquí es la corrección del funcionamiento. ¿De dónde saldrá la corrección del trabajo, si se está dividiendo un duble y se descarta la parte fraccionaria? Puede que de alguna manera milagrosa funcione correctamente, pero se necesita una prueba convincente.

 
Dmitry Fedoseev:

La velocidad necesaria aquí no es la velocidad necesaria, se hace una vez en el inite o por un evento de la GUI. Lo principal aquí es la corrección de la operación. ¿Cómo puede funcionar correctamente si está dividiendo el doblaje y descartando la parte fraccionaria? Puede que de alguna manera milagrosa funcione correctamente, pero se necesita una prueba convincente.

Bueno, si encuentras bugs (que no sean valores como 1kkk+) te agradecería que me dieras pistas.

 
Ilya Malev:

Bueno, si encontráis bugs (excepto en valores como 1kkk+) os agradecería que me dierais pistas.

Y no los buscaré, porque no los voy a usar. Sólo por curiosidad, ¿cómo tienes tanta confianza en que todo será correcto?

 
Dmitry Fedoseev:

Y no lo buscaré, porque no lo voy a usar. Me pregunto cómo puede estar tan seguro de que todo será correcto.

Lo he comprobado con comillas aleatorias y números arbitrarios como 0,7,0,07, 50000000,9991, etc., y además he hecho pruebas de velocidad comparativas. Sólo voy a utilizar esta función, pero no inite, sino mucho más a menudo. Pero en general, si no se baila con panderetas, el Digits habitual es bastante...

 

Encontré un número: 9999999999.9999 - dtd2() devuelve 7 y el mío es 4. Pero es una nimiedad. En general, la función es buena, por fin la entiendo.

 
Dmitry Fedoseev:

Encontré un número: 9999999999.9999 - dtd2() devuelve 7 y el mío es 4. Pero es una nimiedad. En definitiva, la función es buena y por fin la he entendido.

Bueno, eso es lo que dije, yo mismo di un par de estos números arriba.

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

Prueba