Самый простой способ посчитать количество знаков после запятой? - страница 6

 
Aleksey Nikolayev:

Возможно, ошибся в расчётах, посему привожу использованный скрипт:

не в расчетах, а в методике ошибка - оберните во внешний цикл все тело скрипта и запустите раз 10 - тогда увидите хоть какой то тест, а так Ваш скрипт будет выдавать некую случайную по времени выполнения цифру - MQL очень круто оптимизируется во время выполнения кода


т.е. выполните тесты несколько раз (можно тесты поменять местами и еще раз запустить несколько раз для чистоты эксперимента)

 
Igor Makanu:

не в расчетах, а в методике ошибка - оберните во внешний цикл все тело скрипта и запустите раз 10 - тогда увидите хоть какой то тест, а так Ваш скрипт будет выдавать некую случайную по времени выполнения цифру - MQL очень круто оптимизируется во время выполнения кода


т.е. выполните тесты несколько раз (можно тесты поменять местами и еще раз запустить несколько раз для чистоты эксперимента)

Про оптимизацию в курсе, поэтому не просто вычисление, а заполнение массива - иначе циклы игнорируются.

Запускал многократно и в разных видах - просто приведён наиболее простой вид скрипта, где соотношение времён выполнения (в смысле больше/меньше) всегда сохраняется (хотя абсолютные цифры сильно скачут).

PS. Вы оказались правы - при 20-кратном повторении скрипта пришлось добавить ещё преобразование к целому, чтобы получилось всегда медленнее, чем штатная нормализация) Можно ещё просто вместо деления на число делать вычисление логарифма. Перестановка местами особо не повлияла.

В общем, сути моего вывода это не меняет. Подправленный скрипт:

void OnStart()
{
  double step = 1e-4;
  int digs = 4, nstep = 1e6, times = 20;
  double v, vn[], t0, t1, dt1, dt2;
  ArrayResize(vn, nstep);
  for(int j = 0; j < times; ++j)
  {
    // NormalizeDouble()
    t0 = (double)GetMicrosecondCount();
    for(int i = 1; i <= nstep; ++i)
    {
      v = step * i;
      vn[i - 1] = NormalizeDouble(v, digs);
    }
    t1 = (double)GetMicrosecondCount();
    dt2 = t1 - t0;
    // без нормализации
    t0 = (double)GetMicrosecondCount();
    for(int i = 1; i <= nstep; ++i)
    {
      v = step * i;
      vn[i - 1] = v ; // немного быстрее чем NormalizeDouble()
      //vn[i - 1] = (int)(v / step); // немного медленнее чем NormalizeDouble()
      //vn[i - 1] = log(v); // немного медленнее чем NormalizeDouble()
    }
    t1 = (double)GetMicrosecondCount();
    dt1 = t1 - t0;
    Print(dt1, " ", dt2, " ", dt2 - dt1);
  }
}
 

я участвовал в прошлом обсуждении и тестировал на старых версиях МТ5 скрипты - мой пример на первой странице был наиболее производительным, что и логично, там простые арифметические операции, которые процессор щелкает на лету

ошибка до 7-го знака после запятой не должна появляться - там же тестировали и обсуждали

 

Тоже попробовал. Вроде работает корректно! :)

int recDigitsAfterPoint(double num, int counter=0){
   if(MathRound(num)==num) return counter;
   return recDigitsAfterPoint(num*10,counter+1);
}
 
Aleksey Mavrin:

это да, но если такое число 5,3560000000000000000000003 

тут интересны лишь первые три знака после запятой.

Я и говорю,- задают. 

 
Алексей Тарабанов:

Я и говорю,- задают. 

Иногда задают, а иногда обратную задачу решают - как здесь сейчас. 

Это бывает нужно для информационных панелей, чтоб величину лота красиво отображать.

 
Алексей Тарабанов:

Я и говорю,- задают. 

нее, допустим может быть три, четыре, пять, и надо узнать сколько именно.