Пресловутая ошибка Zero divide

 

Перелопатил половину форума, но так и не пойму откуда возникает эта ошибка.

Советник массивный, состоит из программы, подпрограммы и нескольких библиотек.

Использую от 1 до 32 различных индикаторов. И вот пока количество индикаторов где-то до 10-15 этой ошибки почти не встречается, но стоит загрузить его на полную катушку - тут же выскакивает эта ошибка. И то, не всегда, но часто.

Уже пробовал и нормализовывать все данные, но не помогает.

И честно говоря, пока даже не могу определить даже место появления этой ошибки.

В пояснение - мультиперцептронная нейросеть с двумя слоями.

 
Kadet:

Перелопатил половину форума, но так и не пойму откуда возникает эта ошибка.

Советник массивный, состоит из программы, подпрограммы и нескольких библиотек.

Использую от 1 до 32 различных индикаторов. И вот пока количество индикаторов где-то до 10-15 этой ошибки почти не встречается, но стоит загрузить его на полную катушку - тут же выскакивает эта ошибка. И то, не всегда, но часто.

Уже пробовал и нормализовывать все данные, но не помогает.

И честно говоря, пока даже не могу определить даже место появления этой ошибки.

В пояснение - мультиперцептронная нейросеть с двумя слоями.


как один из вариантов - в советнике происходит деление на нулевое значение из неполной истории.

отловить можно принтами

 

Это всегда деление на ноль. Если подобные случаи с момента написания кода не выделяются отладочными средствами, то в большом коде это проблема найти.

У меня советник 40000 строк. Написал для него отладчик на MQL4. Нахожу любую ошибку за несколько секунд.

 
Kadet:

Перелопатил половину форума, но так и не пойму откуда возникает эта ошибка.

Проще не скажешь - деление на нуль. Ищите все арифметические выражения, где есть деление.

Везде, где есть деление, лучше употреблять шаблон

If(b!=0) c=a/b; else c=a (или другой заменитель).

 
Roger:

Проще не скажешь - деление на нуль. Ищите все арифметические выражения, где есть деление.

Везде, где есть деление, лучше употреблять шаблон

If(b!=0) c=a/b; else c=a (или другой заменитель).

Да! Лучшен сразу в принт выводить с указанием блока, функции и программы. А то хрен найдёшь...

Хотя, это может быть штатная ситуация. Тогда надо придумать свои замены результату деления.

 
Соглсен на все 100. В свое время просто вбил себе в голову: если собрался на что-то делить - проверь, не на ноль ли! С тех пор сэкономил минимум пару лет личного и рабочего времени:))
 

Деление на Point - может быть причиной этой ошибки.

https://www.mql5.com/ru/forum/120494

 

Боже... И вы еще программируете...

Ну вот вам уже объяснили:

Используйте конструкцию if знаменатель !=0... Тады делим. Можно в else прописать печать.

Ну вот что сложного???

===

Не! Есть еще у кого бабки брать! )))) // Ace Ventura: Pet Cemetry.!!!

 
Kadet:

Перелопатил половину форума, но так и не пойму откуда возникает эта ошибка.

Советник массивный, состоит из программы, подпрограммы и нескольких библиотек.

Использую от 1 до 32 различных индикаторов. И вот пока количество индикаторов где-то до 10-15 этой ошибки почти не встречается, но стоит загрузить его на полную катушку - тут же выскакивает эта ошибка. И то, не всегда, но часто.

Уже пробовал и нормализовывать все данные, но не помогает.

И честно говоря, пока даже не могу определить даже место появления этой ошибки.

В пояснение - мультиперцептронная нейросеть с двумя слоями.


Деление на ноль это похлеще, чем несбалансированные скобки. Надо по всему коду start'а равномерно расставить Print(). Когда случится ошибка - будет видно между какими принтами она случилась. Дальше, в обозначившемся месте расставить Print() почаще и т.д. пока не будет найдена строка в котрой случается ошибка. Если в найденной строке вызывается функция, то переходим в функцию и в функции расставляем Print(). 

 

Та то, что это деление на ноль - это и коню понятно.

Не понятно откуда оно берётся, ведь при малых объёмах данных его нет, а как только задашь в работу 20-30 рабочих индикаторов - так и выскакивает.

При 10-15 индикаторах - великолепно работает, но хочется более точных прогнозов. Вот и пытаюсь задать больше вариантов.

К тому же if-ы перед всеми возможными делениями - пробовал. Не помогло. И нормализацию пробовал. Тоже не помогло.

Вот подозреваю вот это место, при расчёте логарифма. Там используются максимально большие и минимально малые значения (таких два куска симметричных за исключением мелочей), которые, возможно, из-за нехватки разрядности и представляются как "0". Может они и вылетают как "0", хотя не должны.

А за идею с print-ами большое спасибо. Сам её частенько использую, а тут что-то не догадался.

//+------------------------------------------------------------------------------+
//|                                                                              |
//| Возвращения T*Ln (T/Z), предотвращающий выход за пределы потока              |
//| Внутреннzz подпрограммы.                                                     |
//|                                                                              |
//+------------------------------------------------------------------------------+
double SafeCrossEntropy( double T, double Z ){
//--------------------------------------------
   double Result, R;
//--------------------------------------------
//   Print("Процедура проверки порогов.");
//--------------------------------------------
   if( T==0 )
      return(0);
   else {
      if( MathAbs(Z)>1 )
// Shouldn//t be the case with softmax,
// but we just want to be sure.
         if( T/Z==0 )
            R = MathPow(0.1,300);     // MinRealNumber;
         else
            R = MathAbs(T/Z);
      else 
// В нормальном случае
         if( (Z==0) || (MathAbs(T)>=MathPow(10.0,300)*MathAbs(Z)) )  // MaxRealNumber*MathAbs(Z) )
            R = MathPow(10.0,300);                                   // MaxRealNumber;
         else
            R = MathAbs(T/Z);
       Result = T*MathLog(R);          // MathLog(R);
   }
   return(Result);
}
 

Один раз такое у меня было при присваивании double-значений int-переменным, которые их просто обнуляли и получалось zero divide. Отладка - через пошаговое /* */ комментирование кусков всего кода пока не будет найден и исключен проблемный.

Причина обращения: