Features of the mql5 language, subtleties and tricks - page 143

 
Alexey Viktorov:

You just shouldn't expect that if there is no value, it's necessarily 0 and correspondingly false if it's not a bool-type variable. Even an explicit conversion to bool will not help.

It works this way without errors.

I honestly don't understand where zero comes from at all:

const double Points = TickValue[0] ? Profit / (Lots * TickValue[0] * _Point) : 0; // zero divide

TickValue[0] contains rubbish. It may or may not equal zero.

If trash in TickValue[0] is not equal to zero, then we calculate Points = Profit / Lots * non-zero trash * _Point, otherwise, if trash in TickValue[0] is equal to zero - we equate Points to zero.

And where does the expression Lots * non-zero rubbish * _Point get zero from, if Lots is initialized with one when declared? Isthere zero in _Point?

 
fxsaber:

The error is clear in fact.

OK, the error is unclear. And it's not reproducing for me either.

 
TheXpert:

Ok, the error is incomprehensible. And it doesn't reproduce at me.

Roughly speaking, calling this function may cause division by zero.

// Неправильно написанная функция.
double WrongFunc( const double Num )
{
  return(Num ? 1 / (0.1 * Num) : 0);
}


I encountered this problem in practice in the Report library. Then I realized that it's logical.

 
fxsaber:

Roughly speaking, calling this function can cause division by zero.

I have this code on border dubles, but it does not crash

double f( const double Num )
{
  return(Num ? 1 / (0.1 * Num) : 0);
}

void OnStart()
{
  Print(f(1 e-308));  // 2019.10.28 13:02:19.457	test (USDJPY,H1) inf
}
 
TheXpert:

I get the same code on border dubles, but it doesn't crash

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

void OnStart()
{
  double Num = 0;
  
  _W(Num) = (uchar)2;
  
  Print(WrongFunc(Num));
}
 
fxsaber:
such a cringe.
 
TheXpert:
such a crash.

To summarise, multiplying two non-zero doublets can give zero. And this is not some degenerate case, but a real one in practice.

Roughly speaking, a combat EA can break because of this with far from zero probability.

 
And checking for zero will not save, either explicitly or implicitly (bool conversion)
 
TheXpert:
And checking for zero will not save, either explicitly or implicitly (bool conversion)
  return(0.1 * Num ? 1 / (0.1 * Num) : 0);
 
fxsaber:

To summarise, multiplying two non-zero doublets can give zero. And this is not some degenerate case, but a real one in practice.

Roughly speaking, a combat EA can break because of this with far from zero probability.

on NaN you need to check additionally, most likely this code will workhttp://qaru.site/questions/20557/checking-if-a-double-or-float-is-nan-in-c

f != f

or limit the accuracy, as in CompareDoubles() example - it seems to be in SBhttps://www.mql5.com/ru/docs/basis/types/double

Reason: