Loose pips in simple calculations

 
Hi,
I have been learning to write EA for about a month. I had problem with the calculation of Spread in an EA which gives wrong result, differing just by 1 point between the two form of this equation! The first equation always gave 1 pip lower, whereas the second one gave correct value!
Spread=(Ask-Bid)/Point;       // always gave 1 pip lower than the actual value
Spread=Ask/Point-Bid/Point; // changed to this and getting correct value


I asked my brokerage and they were surprised but could not offer any reason. Their advise to use Normalizedouble was helpful in some other calculation, but did not help here. I know there is another way to get the Spread (using MarketInfo), but I am puzzled by this strange calculation. My Ask and Bid are having correct Digits as checked by Print command with higher accuracy. I have programming experience of more than 15 years (mostly in Fortran) and I do not understand how this loose pip is coming. Also, I am not sure how many such loose pips will be there in any EA I write.
Any explanation and suggestions to reduce this type of error will be greatly appreciated.
Thanks.
chandra

 
Spread in an EA which gives wrong result, differing just by 1 point between the two form of this equation! The first equation always gave 1 pip lower, whereas the second one gave correct value!
Spread=(Ask-Bid)/Point;       // always gave 1 pip lower than the actual value
Spread=Ask/Point-Bid/Point; // changed to this and getting correct value



I presume Spread is an integer variable. Try this
Spread = (Ask - Bid) / Point + 0.000000001; // should do


I asked my brokerage and they were surprised but could not offer any reason. Their advise to use Normalizedouble was helpful in some other calculation, but did not help here.

Too bad for them.
I have programming experience of more than 15 years (mostly in Fortran)

Don't tell anyone. :)

Regards,

mqlexpert {at} gmail {dot} com



 
Thank you Irtron for you suggestion to use that tiny number.

But, unfortunately, I am not looking for a quick fix. I am more interested in why it happens. Also where are all and how often it is known to happen. May be my EA is infested with these loose pips!

The reason I mentioned my experience was that I have never seen such mistakes (atleast after the computer memeory has become big, the precision has never been a problem). So, I am wondering if it is unique to this system!!!

I defined the Spread as integer, but my broker defined as double and still got the same thing.

Regards,
chandra
 
The simple double to int conversion has some problems.
See this topic at mql4.com, I got some answers for a similiar problem:

"MQL4: int x = double y ?"
 
Hi Zap,
Thank you for your pointer.

If such a problem exists, the developers could have made a DoubleToInt internal routine (as you suggested it is not there) in one minute, out of all the hundreds of builds they have released! Or, it should be the bold warning given in the EA documentation section as the first thing. When I mentioned that I had 15 years experience in programming, someone made fun of it (I would not keep any of my programs in this stage for long). So, may be that is not the real problem.

I can make my own routine and see if it fixes all the problems (by addding a 0.000000001 or by NormalizeDouble or MathRound or ALL!). But, still I am skeptical though, because the two equations given in the first post, they both should produce errors, but one does not. In addition, my Broker's code snippet says that they declared everything as double and still got the same error.

Once again thank you Zap.
chandra
 
An example for everyone to understand this problem:

first case: 2+2 the answer is 4 (Which is Correct)

Second case: x=2 , y=2;
x+y the answer is 3 (amazing answer)
 
My one dollar calculator does not mess up anything like that!!!
 
someone made fun


Sorry pal, I didn't mean to insult anyone. My apologies.
I just can't understand how experience or luck of it can turn 1 to 0 in an argument or discussion.

The difference between integer and double is a very basic one. Double value has a limited precision unlike integer which precision is absolute. Any digital computer has this limitation.

Apparently the double result happened to be a tad (= less significant bit) smaller than 4 in the first expression. When the cpu took the value from the fpu it merely cut off all the 9s after 3. by special routine hardcoded in the processor itself. This routine can be considered as DoubleToInt() if you like. This behavior is exact and predictable.

How can the developers know what user needs? When I convert double to integer I always know that I get the integer assigned to the left part before the decimal point of unnormilased double mantissa. And I always know how to interpret the result. That's why I can workaround the discretization error easily and much more transparently and cheaper than any call to a function.

As per the support guys that got it wrong with all the doubles, too bad for them again. The times I believed in magic are all long gone.

Good luck.
 
btw zap forgot to mention this one "MQL4: Apparent bug with MathMod"
 
Hi Irtron,

Thank you for the detailed explanation. If you could explain me one more line for the following example, it will be of great help. (1.9719-1.9710)/0.0001 is the calculation (in gbpusd). It will be calculated first as 0.0009/0.0001 and then as 9.0000 (or is it 8.9999...). The number of digits are fixed and I believe the computers can handle four digits of precision and thats why I am unable to understand how the rounding error comes in. If it was a high precision number it is understandable (in Fortran we casually handled 8 or 16 digits precision, but there we cannot convert Double to Integer, but neverthless 0.0009/0.0001 will be 9.0, not 8.9999... even before we bother about converting to Integer).

Thanks in advance for any further light you might shed on this example. From what you wrote I understand that it is not MQL4 or MT4 problem.

Regards,
chandra


Apparently the double result happened to be a tad (= less significant bit) smaller than 4 in the first expression. When the cpu took the value from the fpu it merely cut off all the 9s after 3. by special routine hardcoded in the processor itself. This routine can be considered as DoubleToInt() if you like. This behavior is exact and predictable.
 
The number of digits are fixed and I believe the computers can handle four digits of precision and thats why I am unable to understand how the rounding error comes in. If it was a high precision number it is understandable (in Fortran we casually handled 8 or 16 digits precision, but there we cannot convert Double to Integer, but neverthless 0.0009/0.0001 will be 9.0, not 8.9999... even before we bother about converting to Integer).

The whole point is that the both integer and double values are represented by binary bits, not by decimal digits internally. Binary integer is lucky to be converted to a decimal one precisely. Double lacks such a luxury. It's precision is restricted by number of bits used for mantissa.
In your case 0.0009 (that is 9 / 1000) has a form of something like n / (2 ** m) where n and m are integers of limited size that is determined by the platform. So it can be as well either 8.9999999999999 or 9.00000000000001 or just 9.

All information regarding machine representation of double type is well googlable I suppose.
Reason: