Why two double vars with equal values result in < comparison at if statement..??

 

I have a script with two iMa (previous and actual (for example) into double var 

   double ima1 = iMA(Symbol(),useTimeFrame,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,1);

   double ima2 = iMA(Symbol(),useTimeFrame,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0); 

   both are equal values:  1.08668 

   but at if statement this result as ima1 < ima2

   if(ima1 < ima2) ....

    

My problem is not the source of vars values (in example above iMA) but the result of if statement with this double vars...

Anyone have a response..???

 

Do you know the troubles with the doubles?

Look here.

So instead of (ima1 < ima2) (use the SRC-button for code !!) you should (must) use:

if (ima2 - ima1 > Point*0.1) ...
 
jdbr69:  both are equal values:  1.08668 
Because they are not equal The == operand. - MQL4 forum
 

OK.

i have more and more years of experience in many progrmatical language as C, C++, C#, Java, etc. and use (normally) a library of functions to solve this problem when I trafer a program between diferent version of compiler / interprete... In this case (mql4) I have only a one year of experiecne and I write many scripts, Ea, classes and lib. First I read all entire online manual an many and many articles... BUT I ignore an important note present in the on line documentations :

https://www.mql5.com/en/articles/1561 said  

                Note that in trading operations it is impossible to use the unnormalized prices, whose accuracy exceeds at least by one digit demanded by a trading server.

                The StopLoss, TakeProfit and Price values for the pending orders should be normalized with the accuracy, which value is stored in predetermined variable Digits. 

 

In section:

3. Function NormalizeDouble

The function NormalizeDouble (double value, int digits) rounds the floating point value to the given precision. Returns normalized value of the double type.

For example:

int start()
  {
   double a=3.141592653589;
   Alert("a=",DoubleToStr(NormalizeDouble(a,5),8));
   return(0);
  }

the result is:

a=3.14159000

Note that in trading operations it is impossible to use the unnormalized prices, whose accuracy exceeds at least by one digit demanded by a trading server.
The StopLoss, TakeProfit and Price values for the pending orders should be normalized with the accuracy, which value is stored in predetermined variable Digits.


4. Check for equality of two double numbers

It is recommended to compare two double numbers using the function CompareDoubles(double number1,double number2) of the stdlib.mq4 library, which looks as:

//+------------------------------------------------------------------+
//| correct comparison of 2 doubles                                  |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2)
  {
   if(NormalizeDouble(number1-number2,8)==0) return(true);
   else return(false); 

  } 

 

 Some confusion was originated for the result o f if statement... in many case it result as aspected by me.

Thanks to Gooly and WhRoeder for cooperation and very fast response. 

 

NormalizeDouble() does NOT what you think it does!

As it returns a double and an double - by its definition and construction - is only the closest approximation to a 'human' number!

What would work would be:

bool CompareDoubles(double number1,double number2)
{
   if(  (int)MathRound((number1-number2)/100000000.0) == 0 ) return(true);
   else return(false); 
}

What if you use:

#define equal(a,b) (fabs((a)-(b))<0.000000001)
...
double x = M_PI;
if ( equal(x,0.0) ) { .. } else { .. }

Hint. Watch your doubles in the debugger!

 
jdbr69: https://www.mql5.com/en/articles/1561 said
Note that in trading operations it is impossible to use the unnormalized prices, whose accuracy exceeds at least by one digit demanded by a trading server.

                The StopLoss, TakeProfit and Price values for the pending orders should be normalized with the accuracy, which value is stored in predetermined variable Digits.

I state the exact opposite: Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
 
WHRoeder:

  • Lot size must also be adjusted to a multiple of LotStep. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.

I was actually quite surprised to discover that a calculated lot size does not need to adjusted to a multiple of LotStep.  MT4 will round it to the nearest correct value . You do need to check the max and min lot size though.
 
GumRai:
I was actually quite surprised to discover that a calculated lot size does not need to adjusted to a multiple of LotStep.  MT4 will round it to the nearest correct value . You do need to check the max and min lot size though.
How do you discover that ? If you saw that somewhere, it's certainly not always true. You have to "normalize" your lot from LotStep.
 
angevoyageur:
How do you discover that ? If you saw that somewhere, it's certainly not always true. You have to "normalize" your lot from LotStep.
 Yes, you are right, it is only if the lot step is 0.01. If the calculated lot size is 0.0123, 0.01 will be used
Reason: