# is this comparison safe for non constant data ?

if(samples[i].outcomes[ix_of_class]==1.0)

this is not safe to use right ? i mean it can spit out 0.9999999999999 or something and it will not pass the check

Lorentzos Roussos:this is not safe to use right ? i mean it can spit out 0.9999999999999 or something and it will not pass the check

No it is not safe! Equality comparison of doubles is not reliable.

But you already know this, so why the question? Is there something specific reason behind the question?

Doubles are rarely equal. Understand the links in:
The == operand. - MQL4 programming forum #2 (2013)

Fernando Carreiro #:

No it is not safe! Equality comparison of doubles is not reliable.

But you already know this, so why the question? Is there something specific reason behind the question?

Yeah , can this occur with a constant too ? so if i initialize it can it be butchered if i move it around (copy array) ?

thanks

William Roeder #:

Doubles are rarely equal. Understand the links in:
The == operand. - MQL4 programming forum #2 (2013)

thanks

Lorentzos Roussos #: Yeah , can this occur with a constant too ? so if i initialize it can it be butchered if i move it around (copy array) ?

It might be safe with constants, but I personally would not rely on that.

I always assume that is not safe and use a different approach, to make sure to be on the safe side.

Fernando Carreiro #:

It might be safe with constants, but I personally would not rely on that.

I always assume that is not safe and use a different approach, to make sure to be on the safe side.

aha

so this is relatively safe too ? the senario here is the maximum double from a set can be moved around and be subtracted , so if the maximum value is subtracted by the -real world would be - equal ,the result can be 0.0000000000000001 so instead of ==0.0 i can <0.001 or somtheing , like so ?

if(amounts[i]<0.001){
zero_amounts++;
}

If you use literals (like x = 1.003) to assign the variables and not doing math calculations on these variables, then their values will never change, and you can compare using == != >= <= > < relational operators.

int x = 0.2;
Print(x == 0.2);  // true

But when you start doing math calculations (+ - * / % ) or use math functions (NormalizeDouble, etc..) or assign a variable from a math expression, tiny errors will accumulate into the result (called, round-off errors). So, using exact comparisons (like the above) after doing math with doubles will give you unexpected results.

For example:

int x = 0.2;
int y = x + 0.1;   // math calculations can introduce round-off errors
Print(y == 0.3);   // false

To get the expected results for comparisons after floating-point calculations, you should switch to loose comparisons.

Use these macros (or any other equivalent code) to perform loose comparisons of doubles:

#define nearlyEqual(x, y)   MathAbs(x - y) < 1.0e-8
#define EQ(x, y)      (x == y || nearlyEqual(x, y))
#define GTE(x, y)     (x >= y || nearlyEqual(x, y))
#define LTE(x, y)     (x <= y || nearlyEqual(x, y))
#define NE(x, y)      (x != y && !nearlyEqual(x, y))
#define GT(x, y)      (x >  y && !nearlyEqual(x, y))
#define LT(x, y)      (x <  y && !nearlyEqual(x, y))

In the above code: 1.0e-8 (which is 0.00000001) is the maximum accepted difference (epsilon) between to doubles to consider them equal. You can change it, according to which doubles you compare (for example TICK_SIZE or VOLUME_STEP), but generally using very small values is better like 1e-8 or 1e-10.

int x = 0.2;
int y = x + 0.1;   // math calculations can introduce round-off errors
Print(y == 0.3);   // false

Print(EQ(y, 0.3)); // true as expected.

Edited: 1e-8 or whatever is the "maximum" accepted difference (not the "minimum").

amrali #:

If you use literals (like x = 1.003) to assign the variables and not doing math calculations on these variables, then their values will never change, and you can compare using == != >= <= > < relational operators.

But when you start doing math calculations (+ - * / % ) or use math functions (NormalizeDouble, etc..) or assign a variable from a math expression, tiny errors will accumulate into the result (called, round-off errors). So, using exact comparisons (like the above) after doing math with doubles will give you unexpected results.

For example:

To get the expected results for comparisons after floating-point calculations, you should switch to loose comparisons.

Use these macros (or any other equivalent code) to perform loose comparisons of doubles:

In the above code: 1.0e-8 (which is 0.00000001) is the minimum accepted difference (epsilon) between to doubles to consider them equal. You can change it, according to which doubles you compare (for example TICK_SIZE or VOLUME_STEP), but generally using very small values is better like 1e-8 or 1e-10.

Thank you very much .

edit : the "artifact" is not constant i assume , like the "deviation" wont always be  1.0e-8 for instance ?

See William's answer and explanation: https://www.mql5.com/en/forum/136997/page2#comment_3470322

Can price != price ? - How to make the most of a double calculation?
• 2011.12.09
• www.mql5.com
*shakes his tie into position with two fingers* only use normalize double in calculations involving a double value not just everywhere there is a double. I arrived at this solution which turns doubles into ints for the purpose of comparing doubles

Drazen Penic #:

See William's answer and explanation: https://www.mql5.com/en/forum/136997/page2#comment_3470322

Thanks , not dealing with price values though where the digits are known , although the data is normalized so it can be derived since i'm scanning it anyway.

Lorentzos Roussos #:

Thank you very much .

edit : the "artifact" is not constant i assume , like the "deviation" wont always be  1.0e-8 for instance ?
Please explain it more. I could not understand it.