Get the number of decimal places of any numbers (not just quotes) bypassing Digits() in MQL4 and MQL5 - page 13

 
Dmitry Fedoseev:

This one: f/=0.0000001; is questionable.

I agree, billions in the tester can be glitchy. otherwise it's OK )

 

12'345'678'987.9991-1

12'345'678'987.9991-2

 

And this is twice as fast with the same result

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:

And this is twice as fast with the same result

This is not the speed you need here, it's done once in the inite or by GUI event. The main thing here is the correctness of operation. Where will correctness of work come from, if a duble is being divided, and the fractional part is being discarded? Maybe it somehow miraculously works correctly, but you need a convincing test.

 
Dmitry Fedoseev:

The speed needed here is not the speed needed, it is done once in the inite or by a GUI event. The main thing here is the correctness of the operation. How can it work correctly if it's dividing the dubble and discarding the fractional part? Maybe it somehow miraculously works correctly, but you need a convincing test.

Well, if you find bugs (other than values like 1kkk+) I would be grateful for hints.

 
Ilya Malev:

Well, if you find bugs (except for values like 1kkk+) I would be grateful for hints.

And I won't look for them, because I'm not going to use them. Just curious, how do you have such confidence that everything will be correct?

 
Dmitry Fedoseev:

And I won't look for it, because I'm not going to use it. I'm just wondering how you can be so sure that everything will be correct?

I checked on random quotes and arbitrary numbers like 0.7,0.07, 50000000.9991 etc., and besides I did comparative speed tests. I am just going to use this function, but not in inite, but much more often. But in general, if you don't dance around with tambourines, the usual Digits is quite enough...

 

Found one number: 999999999999.9999 - dtd2() returns 7 and mine is 4. But it's a trifle. All in all, the function is good, I finally understand it.

 
Dmitry Fedoseev:

Found one number: 999999999999.9999 - dtd2() returns 7 and mine is 4. But it's a trifle. All in all, the function is good and I finally understood it.

Well, that's what I said, I gave a couple of these numbers above myself.

 
#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