Question to the MQL4 masters. Again about Double Compare. - page 5

 

Amazing conclusion! What makes you think that with any digit, if you don't even "understand" what a digit is at all?

 
Integer:

Amazing conclusion! What makes you think that with any digit, if you don't even "understand" what a digit is at all?

Are you starting to pick on words? Obviously, this is going to be a personality assassination. :)
I should say at once that I prefer not to participate in such explanations, because if you have nothing to say on the merits, why talk at all?
 
VBAG:
I'd like to thank all the pros for their insight!

Irtron, I chose your variant, I liked it very much. I corrected it a little for general cases and checked it:

int ComparePrice(double a, double b, double digit)
{
a -= b;
b = digit;
if (a > b)
return (1);
if (a < -b)
return (-1);
return (0);
}
Thanks.
I forgot to clarify that I want to pass any predefined value into digit:
double digit14=0.00000000000001;
double digit12=0.000000000001;
double digit8=0.00000001;
double digit4=0.0001;
double digit2=0.01;
which will determine the required accuracy.
For this functionality, it works very quickly.
Irtron, thanks again.

 
Irtron:
Integer:

Amazing conclusion! What makes you think that with any digit, if you don't even "understand" what digit is at all?

Starting to pick on words? Obviously, the next step is going to be a personality assassination. :)
I should say at once that I prefer not to participate in such explanations, because if you have nothing to say on the merits, why talk at all?


Why pick on, I just read what you wrote. Your understanding is obviously hampered by "your blatant... (you name the word)"

VBAG, why reinvent the wheel when there is a function NormalizeDouble() that compares two numbers faster than ComparePrice()?

 
Integer:

VBAG, why reinvent the wheel when there is a NormalizeDouble() function that compares two numbers faster than ComparePrice()?

The function compares two double numbers and gives the answer <, > or = to 14 decimal places. (NormalizeDouble() is limited to 8 digits)
If you can suggest a similar bike or better alternative solutions, I would be happy to use them.
Respectfully,
Vladimir
 
VBAG:
Integer:

VBAG, why reinvent the wheel when there is a NormalizeDouble() function that compares two numbers faster than ComparePrice()?

The function compares two double numbers and gives the answer <, > or = to 14 decimal places.(NormalizeDouble() is limited to 8 digits)
If you can suggest a similar wheel or better alternatives, I'd be happy to use them.
Respectfully,
Vladimir
Here is a test for my interest:
int start()
  {
//----
    double a = 1.23450001, b = 1.23449999;
 
    int start1 = GetTickCount(), c1;
    for ( c1 = 0; c1 < 100000000; c1 ++ ) CD( a, b,0.00000001);
    int end1 = GetTickCount();
    
 
    int start2 = GetTickCount(), c2;
    for ( c2 = 0; c2 < 100000000; c2 ++ )   xNormalize(a,b,8);
    int end2 = GetTickCount();
 
    Print( "CD: ", (end1-start1), ", xNormalize: ", (end2-start2) );
 
    return(0);
   }
 
//+ CompareDouble ---------------------------------------------------+ CompareDouble
int CD(double a, double b, double digit)
{
    a -= b;
    b = digit;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
// Две операции NormalizeDouble----
bool xNormalize(double a, double b,int digit)
  {
   double d1 = NormalizeDouble(a,digit);
   double d2 = NormalizeDouble(b,digit);
   
//   bool bCompare=d2-d1 > 0.0;
   bool bCompare= 0;
   return(bCompare);
2007.09.12 07:15:09 $CheckCompareDouble USDJPY,M5: CD: 20485, xNormalize: 51265

Conclusion:
The CD function compares two double numbers , gives the answer <, > or = with 14 decimal places and works 2 times faster than simply performing NormalizeDouble()(even without logic to compare them).
 
Yes, two calls to NormalizeDouble() takes longer than CD, and one call is faster. Accuracy of 14 digits is a nice touch :-)
 
I've been trying to compare real numbers recently too!

Many people write that for comparing must use built-in function NormalizeDouble(). (this is what the developers recommend too).
Therefore, I would first like to define: "what is NormalizeDouble()?", i.e. how it works, what is its algorithm.

MQL4 Reference - Data Conversions - NormalizeDouble

Rounding a floating point number to a specified precision.
...

I don't know how rounding is organized in MQL4 (ask the developers), but I know a standard method Rounding floating point numbers to specified precision:
Here, a function:

double MyNormalizeDouble(double value, int digits)
{
    int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                      с помощью которого мы из VALUE сделаем целое число
    double result = MathRound(factor * value) / factor;
    
    return(result);
}
From this function you can see that we first go from a real number to an integer, and then back to a real number again.
For comparison, it is enough to go to an integer only.

Therefore, I believe the fastest and most reliable way to compare real numbers is to convert them to integers.
This is what the comparison will look like:

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

All this can be formatted into a function and used. It's a pain to write, it seems to be clear how to make a function!
I think this way is faster than calling NormalizeDouble().

To be safe, you can also make MathRound() function return an integer, since by default it returns double.
The easiest way to do it this way

int MyMathRound(double value)
{
    int result = MathRound(value);
    return(result);
}
Then only integers will be compared, and they compare well!


I think this way is the most correct, don't you?
 
gravity001:

So I think the quickest and most reliable way is to convert the real numbers to integers
The comparison would look like this:

double a;
double b;
int factor = MathRound( MathPow(10, digits) ); // digits - это точность с которой будем сравнивать
                                                           Если сравниваем цены, то это предопределенная переменная Digits
...

if (MathRound( (а - b) * factor )  !=  0)
{
    ... // a != b
}

if (MathRound( (а - b) * factor )  ==  0)
{
    ... // a == b
}

if (MathRound( (а - b) * factor )  >  0)
{
    ... // a > b
}

if (MathRound( (а - b) * factor )  <  0)
{
    ... // a < b
}

I think that's the right way to do it, don't you?

I don't think so. Judge for yourself:
The whole beauty of Irtron's code is in its compactness (absolutely nothing extra - even variables are saved!).
And you suggest we should add two more operations for every
(а - b)
operation at least.
(MathRound( (а - b) * factor ) 
That's a speed advantage!
 
VBAG:
I don't think so. Judge for yourself

Yes, a little slower:
int start()
{
    double a, b;
    int start1, start2, end, c;
    
    a = 1.23450001;
    b = 1.23449999;
    
    start1 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        ComparePrice(a, b,0.0001);
    
    start2 = GetTickCount();
    
    for (c = 100000000; c > 0; c--)
        intCompare(a, b,10000);
    
    end = GetTickCount();
 
    Print("ComparePrice: ", start2 - start1, ", intCompare: ", end - start2);
 
    return(0);
}
 
int ComparePrice(double a, double b, double point)
{
    a -= b;
    b = point / 2.;
    if (a > b)
        return (1);
    if (a < -b)
        return (-1);
    return (0);
}
 
int intCompare(double a, double b, int factor)
{
    return(MathRound( (a-b) * factor ));
}
ComparePrice: 32032, intCompare: 35296