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

 
SK. писал (а):
VBAG:
I wouldn't expect that from you.

I take it back.
Glad I was wrong in my doubts.
 

TO SK.

You know best. I don't consider MQL a programming language. It's just such a DIALECT.

By the way, I'm sick of two things in it:

1) no enumeration of operations, i.e. curly brackets

2) return - you're awfully tired of parentheses.

All in all, well done guys.

Kernighan and Ritchie - a round of applause for them.

 
VBAG писал (а):
I take that back.
Glad I was wrong in my doubts.


We didn't have an argument :)

Depfy:

I don't consider MQL to be a programming language. It's just such a DIALECT.

It's probably a question of terminology. I, for example, find in MQL all the attributes of a complete language. In any case, it is one of the few languages (noticeably, the best one) that allows traders to mechanize and automate their activities. I think this language is quite satisfactory at least in the sense that its possibilities many times exceed the needs of most algorithms (in other words - if there were enough well-thought-out ideas, and means for their implementation are already available).
 
SK. писал (а):
...

As it stands, the initial value of the variable 123.00000000000 may turn out to be 122.99999999999999 by the time it is used in the calculations. And this is despite the fact that since the variable was discovered, its value has never changed, but it has only been requested by the program to take part in other calculations.


This is actually why there was all this fuss. That is why we have decided to use NormalizeDouble() as close as possible to actual calculation, preferably right in condition of if, for, while statements.

Are you sure of what you are saying? If you can specify the source of your knowledge?

Then I have this question for you

1? if the problem is remembering or reading a variable, how can NormalizeDouble() help if the return value is also remembered or read with an error?
2? Why the scheme NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits), where !OC! - comparison operator, doesn't it always work? even if it is inserted directly into if?
3? Do you know how NormalizeDouble() works (function algorithm)?
4? i wrote my opinion on this, what do you think ?

gravity001 wrote (a):

...
I already told you about normalization. First tell me why you need to apply it and then how and where.

That's the key question, isn't it? I've been thinking about it for a long time myself: "you enter double and you get double ". What could possibly change?
I haven't found the exact answer. But I imagine it's like this

double a = 2.000000000000
double b = 2.000000000001
double c = 1.999999999999

All these variables are different and are stored in memory accurate to the last digit!
In this case, we ourselves define the signs (digits). Everything that is not defined is filled with zeros.

If we had defined double a = 2.0, and it is stored in memory as 2.0000001 or 1.9999999, it is clear that NormalizeDouble() would not help, because it would return an inaccurate value!
I think such an error occurs almost never when memorizing a variable value. Besides, I don't think number 2.0 is stored as 1.99999999999999999 on purpose, since each character (digit or point) is stored with a specific bit in the bit-string! Therefore, the number 2.0 is safely stored as 2.00000...00.

The other case is when we do not determine the signs ourselves:

a = 4.0;
b = 2.0;
c = a / b // - the "division" operation is done by the processor, or rather by the co-processor, and it fills the premenent with characters (digits).

After the operation it can be:
Most commonly:
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

i.e. the result often differs from the true value by a small amount.

Large errors occur very rarely:
с = 2.3

Here, there are two explanations:
1) part of the bit string was affected in memory when calling a or b, i.e. variables a and b were changed.
2) an error occurred during the "divide" operation.

I think 2) occurs most often. Why I don't know. I think it has to do with the fact that the co-processor is intended to be highly optimized to the detriment of uselessness.

When comparing a variable to number 2.000...00, equality will obviously fail. Not all the bits will be equal.

Now, NormalizeDouble() is here to help!
NormalizeDouble() will "fix" this small error!
Since the error is most often very small, rounding with a small precision will always give the correct result.

Look at it this way:
Round the number a = 2.111...11 to the second digit.
NormalizeDouble() will write 2.11 into a new variable and fill in the remaining bits with zeros, not ones!
I think it will look like this:

double MyNormalizeDouble(double value, int digits)
{
     int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                       с помощью которого мы из VALUE сделаем целое число
     double result = MathRound(factor * value) / factor;
     return(result);
}
Here, I tried my best to explain why NormalizeDouble() is needed.

Until recently I was completely satisfied with this explanation, but have recently got convinced myself that this scheme does not always work

NormalizeDouble(a, 2) ! NormalizeDouble(b, 2) where !OC! - is a comparison operator.
Although according to my understanding it must always work!
Therefore, I will be glad to receive any reasoned and understandable criticism!
 
gravity001:
SK. wrote (a):
...

As it stands, the initial value of the variable 123.00000000000 may turn out to be 122.99999999999999 by the time it is used in the calculations. And this is despite the fact that since the variable was discovered, its value has never changed, but it has only been requested by the program to take part in other calculations.

This is actually why there was all this fuss. That's why I had to use NormalizeDouble() as close as possible to the actual calculation, preferably directly in the condition of if, for, while statements.

Are you sure of what you are saying? If you could indicate the source of your knowledge?
I am sure. The source of your knowledge is your own experience in MQL4 programming and consultations of developers.
1? If the problem is in remembering or reading a variable, how can NormalizeDouble() help, if the return value is also remembered or read with an error?
NormalizeDouble() should be applied immediately before the comparison operation. The result of comparison operation is a value of boolean type, which is never "corrupted".
2? Why the scheme NormalizeDouble(value, digits) ! NormalizeDouble(value, digits) , where !OC! is the comparison operator, doesn't always work? Even if you insert it directly into if?
I didn't say so. That's exactly how it works and that's what you should do.
3? Do you know how NormalizeDouble() (function algorithm) works?
No, I do not. Please refer it to the developers.
4? I wrote my opinion on this subject, what do you think?
Your opinion is interesting, but this question has long been solved. It is better to use developers' recommendations and not to reinvent the wheel.
 
SK. писал (а):
gravity001:

2? Why does the scheme NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , where !OC! is a comparison operator, doesn't always work, even if you insert it directly into if?
I didn't say so. That's exactly how it works and that's how you should do it.

Here are more opinions on this subject

'Again about comparing two doubles', 1 page from the very first post!

Integer 24.12.2006 15:23

Unfortunately, the NormalizeDouble(x-y,Digits) construction is not identical to the NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) construction

Renat 24.12.2006 16:15

And it shouldn't be identical. The first one is correct.

I think the construct is
if (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
and the construction
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
are identical!

What do you think?
 
gravity001:

Renat 24.12.2006 16:15

And it must not be identical. The first is correct.

I think the construction
if(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
and the construction
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
are identical!

What do you think?


And Renat's opinion is not interesting? You are not interested in the opinion of the CEO of the company that develops MT?

Or are you like the old woman in Pushkin's fairy tale? Just want-want-want-want! Remember how the tale ends. "The fish said nothing. She wagged her tail and swam away to the blue sea. He waited by the sea for a long time for an answer. He didn't wait, he turned back to the old woman..."

 
SK. писал (а):
The first is gravity001:


Renat 24.12.2006 16:15

And it must not be identical. The first one is correct.

I think the construction
if(NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
and the construction
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
are identical!

What do you think?



And Renat's opinion is not interesting? You are not interested in the opinion of the CEO of the company that develops MT?


Or are you like the old woman in Pushkin's fairy tale? Just want-want-want-want! Remember how the tale ends. "The fish said nothing. She wagged her tail and swam away to the blue sea. He waited by the sea for a long time for an answer. He didn't wait, he turned back to the old woman..."



Well, Renat said the first way is right and the second is wrong, and you said the second way is right, right?

2? Why the scheme NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , where !OC! is a comparison operator, doesn't always work, even if you insert it directly into if?
I didn't say so. That's exactly how it works, and that's how it should be done.
 

I said so in the sense of a more-or-less comparison:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))

meaning that constructions of the type do not always work:

double a = NormalizeDouble(x,Digits);
double b = NormalizeDouble(y,Digits);
 
if (a > b)
  {
  ...
  }

i.e. NormalizeDouble() should be inserted right into operator's header, as close as possible to where the comparison operation is calculated.

As for the developers' opinion, I don't intend to dispute it.

And then... that thread dealt with an entirely different construct:

 
SK. писал (а):

I said so implying a more-or-less comparison:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))
I didn't check for more or less, but I did check for equality.
I had comparison errors when I used this construction:

if (NormalizeDouble(x, digits) == NormalizeDouble(y, digits))
{
    ...
}
Why, don't you know?
Reason: