Получаем количество десятичных знаков после запятой любых чисел (не только котировок) в обход Digits() на MQL4 и MQL5 - страница 13

 
Dmitry Fedoseev:

Вот это вот: f/=0.0000001; вызывает сомнения. 

Согласен, миллиарды в тестере могут подглючивать. в остальных случаях ничего страшного )

 

12'345'678'987.9991-1

12'345'678'987.9991-2

 

А вот так вдвое быстрее с тем же резалтом

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:

А вот так вдвое быстрее с тем же резалтом

Здесь не нужная скорость, это делается один раз в ините или по событию ГУИ. Главное здесь нужна правильность работы. Откуда будет правильность работы, если выполняется деление дабла, да еще отбрасывание дробной части? Может оно каким-то чудом и работает правильно, но нужно убедительный тест провести.

 
Dmitry Fedoseev:

Здесь не нужная скорость, это делается один раз в ините или по событию ГУИ. Главное здесь нужна правильность работы. Откуда будет правильность работы, если выполняется деление дабла, да еще отбрасывание дробной части? Может оно каким-то чудом и работает правильно, но нужно убедительный тест провести.

Ну если найдете баги (кроме значений типа 1кккк+) буду благодарен за подсказки.

 
Ilya Malev:

Ну если найдете баги (кроме значений типа 1кккк+) буду благодарен за подсказки.

И искать не буду, потому-что использовать не собираюсь. Просто интересно, откуда у вас такая уверенность, что все будет правильно?

 
Dmitry Fedoseev:

И искать не буду, потому-что использовать не собираюсь. Просто интересно, откуда у вас такая уверенность, что все будет правильно?

Я проверил на рандомных котировках и произвольных цифрах типа 0.7,0.07, 50000000.9991 и т.п., и кроме этого провел сравнительные тесты по скорости. Я как раз если и буду использовать эту функцию, то не в инит а гораздо чаще. А так вообще если с бубнами не плясать, то обычного Digits вполне хватает...

 

Нашел одно число: 9999999999.9999 - dtd2() возвращает 7, а моя 4. Но это мелочь. В общем функция хорошая, понял я ее, наконец-то.

 
Dmitry Fedoseev:

Нашел одно число: 9999999999.9999 - dtd2() возвращает 7, а моя 4. Но это мелочь. В общем функция хорошая, понял я ее, наконец-то.

Ну я и говорил об этом, выше сам приводил пару таких чисел.

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

Тест