I use integers for prices. The minimum step in the price value is one Point. It is a constant, has a fixed size, i.e. a discrete value. But discreteness is also a property of _ integers. Therefore, by converting prices to an integer (int), you can perform calculations without loss of precision.
For example:
EUR/USD quote = 1.17191, convert to int, we get 117191;
TakeProfit=0.00500, in int we get 500;
ТР=117191+500=117691.
I use price arrays in my programme. I easily compare them if(a==b), NormalizeDouble() normalisation is not required. I use double numbers only when accessing the server, when receiving quotes, and when sending OrderSend().
In the Print() function, I use a record like ".117191" or ".085338". It is quite clear.
I use integers for prices. The minimum step in the price value is one Point. It is a constant, has a fixed size, i.e. a discrete value. But discreteness is also a property of _ integers. Therefore, by converting prices to an integer (int), you can perform calculations without loss of precision.
For example:
EUR/USD quote = 1.17191, convert to int, we get 117191;
TakeProfit=0.00500, in int we get 500;
ТР=117191+500=117691.
I use price arrays in my programme. I easily compare them if(a==b), NormalizeDouble() normalisation is not required. I use double numbers only when accessing the server, when receiving quotes, and when sending OrderSend().
In the Print() function, I use a record like ".117191" or ".085338". It is quite clear.
What you do is called fixed-point arithmetic, and you have to take care of the scale factor (e.g. scale = 100 000 for 5-digits prices) throughout all calculations.
However, it is not the most efficient way on MT5 platform, because originally the prices and lots are recieved as "double" floating-point.
A minor bug that I had prevoiusly reported in NormalizeDouble() function where small round-off errors (= 1 ULP; unit in the last place) is frequently introduced in the function output.
If you want "very" precise rounding to the least significant bit (ULP), pleasae use my library function Round(num, digits) from "math_utils.mqh".
//+------------------------------------------------------------------+//| Round to a specified number of decimal digits (no-round off). |//+------------------------------------------------------------------+double Round(constdouble value, constint digits)
{
double pwr10 = MathPow(10, digits);
returnMathRound((value * pwr10) * (1 + DBL_EPSILON)) / pwr10;
}
math_utils.mqh contains a rather optimized version of Round() for speed.
BTW, in older versions of MT5, Print() function had errors when printing doubles, so it was very hard to detect where exactly the fp roundoff errors occur.
The Print() function is now assumed to be correct in MT5 (I did not test Print() on MT4).
Edit2:
Another issue in your code is the exact comparison of doubles (calculated values)
Print(d2 == NormalizeDouble(d2, 8)); // false
You should use loose (more tolerant) comparison using the absoulte difference as before
double a = (string)"1.00544";
double b = NormalizeDouble(a, 8);
// check if a, b are almost equalPrint( MathAbs(a - b) < DBL_EPSILON * MathMax(MathAbs(a), MathAbs(b)) ); // true
Why are you thinking the problem is normalizedouble (it could be but we have no idea about it) when stringtodouble give 1. To check if conversion string -> double is correct, we can examine it here https://baseconvert
Allow the use of cookies to log in to the MQL5.com website.
Please enable the necessary setting in your browser, otherwise you will not be able to log in.
You are signed in. Two-factor authentication has been disabled. Set it up again and scan a new QR code, or continue with two-factor authentication disabled.
In fact, in all others with double numbers.
you don't have to compare in robotsAnd why did you suddenly start discussing the comparison of double variables if the original question was
Forum on trading, automated trading systems and testing trading strategies.
Peculiarities of mql5 language, subtleties and techniques of work
Andrei Iakovlev, 2025.05.19 14:56
Some variable has a value equal to -1.
Which check will be executed faster to check this value: < 0 or == -1?
And further suggested
Forum on trading, automated trading systems and testing trading strategies
Peculiarities of mql5 language, subtleties and techniques of work
Putnik, 2025.06.25 18:31
It is better to replace a==b with (a-b)==0 , it is better.
Better how? As in that anecdote... "better than ...".
It is better to replace a==b with (a-b)==0 , it is better.
I think this is only meaningful (and may be more error tolerant if either a or b is a calculated value) for comapring doubles a and b.
For doubles:
or
For integers:
a==b is better (and more clear)
I use integers for prices. The minimum step in the price value is one Point. It is a constant, has a fixed size, i.e. a discrete value. But discreteness is also a property of _ integers. Therefore, by converting prices to an integer (int), you can perform calculations without loss of precision.
For example:
EUR/USD quote = 1.17191, convert to int, we get 117191;
TakeProfit=0.00500, in int we get 500;
ТР=117191+500=117691.
I use price arrays in my programme. I easily compare them if(a==b), NormalizeDouble() normalisation is not required. I use double numbers only when accessing the server, when receiving quotes, and when sending OrderSend().
In the Print() function, I use a record like ".117191" or ".085338". It is quite clear.
I use integers for prices. The minimum step in the price value is one Point. It is a constant, has a fixed size, i.e. a discrete value. But discreteness is also a property of _ integers. Therefore, by converting prices to an integer (int), you can perform calculations without loss of precision.
For example:
EUR/USD quote = 1.17191, convert to int, we get 117191;
TakeProfit=0.00500, in int we get 500;
ТР=117191+500=117691.
I use price arrays in my programme. I easily compare them if(a==b), NormalizeDouble() normalisation is not required. I use double numbers only when accessing the server, when receiving quotes, and when sending OrderSend().
In the Print() function, I use a record like ".117191" or ".085338". It is quite clear.
What you do is called fixed-point arithmetic, and you have to take care of the scale factor (e.g. scale = 100 000 for 5-digits prices) throughout all calculations.
However, it is not the most efficient way on MT5 platform, because originally the prices and lots are recieved as "double" floating-point.
BTW, here is a more precise way to compare doubles a & b (i.e., calculated values, not constants) for equality:
As this comparison can handle very big or very small numbers gracefully.
Edit:
For other forms of comparisons (>, <, etc) please check my library here: https://www.mql5.com/en/code/20822
BTW, here's a more accurate way to compare the dual numbers a and b (i.e. calculated values, not constants) for equality:
Since this comparison can handle very large or very small numbers gracefully.
Is d1 or d2 normalised?
A minor bug that I had prevoiusly reported in NormalizeDouble() function where small round-off errors (= 1 ULP; unit in the last place) is frequently introduced in the function output.
If you want "very" precise rounding to the least significant bit (ULP), pleasae use my library function Round(num, digits) from "math_utils.mqh".
Edit:
A "precise" Round function can be implemented as:
math_utils.mqh contains a rather optimized version of Round() for speed.
BTW, in older versions of MT5, Print() function had errors when printing doubles, so it was very hard to detect where exactly the fp roundoff errors occur.
The Print() function is now assumed to be correct in MT5 (I did not test Print() on MT4).
Edit2:
Another issue in your code is the exact comparison of doubles (calculated values)
You should use loose (more tolerant) comparison using the absoulte difference as before
If you need "very" precise rounding to the least significant bit (ULP), please use my library function Round(num, digits) from"math_utils.mqh".
I need a fast decompression of the compressed MqlTick. This option is unfortunately slow.