MathMod Anomalies, could someone explain this ?

 

i have code like this:

double currentprice=1.36350000;
double cek_digit_point=0.00010000;
int pos_distance=3;


Alert(MathMod((currentprice/cek_digit_point),pos_distance)+" "+MathMod(13635.00000000,pos_distance));


Alerts Result: 3.00000000 0.00000000

i would to do modulus operation...

it supposed to be same result isn't ?


could someone tell me why ?

 

To make long story short.. just try below code:


Alert(MathMod((13635/1),3)+" "+MathMod((1.36350000/0.0001),3));


i think, mathematically, both return same result...

 
veeco:

To make long story short.. just try below code:


Alert(MathMod((13635/1),3)+" "+MathMod((1.36350000/0.0001),3));


i think, mathematically, both return same result...

the first is an integer divided by an integer while second is a double divided by a double

 
ronaldosim:

the first is an integer divided by an integer while second is a double divided by a double

Indeed. The processor's floating point unit calculates 1.3635 / 0.0001 as 13634.999999999998. For the call to MathMod this effectively gets treated as MathMod(13634, 3) rather than MathMod(13635, 3). Hence the different results.


Have a look at the countless topics in this forum (e.g. 'MQL4 MathCeil() intermittantly returns wrong result') about double arithmetic and the need to use NormalizeDouble() in contexts such as this.

 

yes, NormalizeDouble will do the job well, eventhough i still confuse on how this process could mislead user (especially when you use EA) because not all values returned is wrong but only for specific numbers.


So bottom line, could you suggest me, which operation need normalizedouble ? or all double's data type need to be normalized first before we use it ?

 
veeco:

So bottom line, could you suggest me, which operation need normalizedouble ? or all double's data type need to be normalized first before we use it ?

In principle, any calculation of a double value where your subsequent use of it then implies a particular amount of precision.


In practice, based on the posts to this forum, there are two types of scenario which commonly catch people out. Firstly, scenarios where the double value is implicitly expected to contain an integer. This applies both to your example and to the one I linked to before ('MQL4 MathCeil() intermittantly returns wrong result'), and in this case you can also use MathRound() rather than NormalizeDouble(). Secondly, comparison of two double values - see, for example, 'Conditional Statement failure... [At wits end] if ( 1.4225 > 1.4225) is NOT TRUE!!!!!!'.


In theory you are supposed to use NormalizeDouble() before passing prices and lot sizes to OrderSend(), but I've never yet seen a broker who doesn't in effect do this themselves.


(People often complain that all this is a "bug" in MetaTrader. It isn't. But the thing which really doesn't help is that MetaTrader uses 15+ decimal places of precision internally, but can only display 8 decimal places via things such as DoubleToStr. That does come close to being a bug.)

Reason: