Bug in MetaEditor Build 3566: Wrong display of double floating point numbers in the debugger window
Floating-point has an infinite number of decimals, it's you, not understanding floating-point and that some numbers can't be represented exactly. (like 1/10.)
Double-precision floating-point format - Wikipedia
See also The == operand. - MQL4 programming forum (2013)
If you want to see the correct number of digits, convert it to a string with the correct/wanted accuracy.
question about decima of marketinfo() - MQL4 programming forum (2016)
Floating-point has an infinite number of decimals, it's you, not understanding floating-point and that some numbers can't be represented exactly. (like 1/10.)
Double-precision floating-point format - Wikipedia
See also The == operand. - MQL4 programming forum (2013)
If you want to see the correct number of digits, convert it to a string with the correct/wanted accuracy.
question about decima of marketinfo() - MQL4 programming forum (2016)
Enough using copy and paste!
Try to use something else, please.
If two numbers are equal, then you should choose the visualization of the number with the least number of digits.
string GetCloneNumber( const double Num ) { string Str = (string)Num; int Count = 1; while (Num != (double)(Str + IntegerToString(1, Count, '0'))) Count++; Str += IntegerToString(1, Count, '0'); return(Str); } void DoubleProperty( const double Num ) { const string Str = GetCloneNumber(Num); const double Num2 = (double)Str; Print((string)Num + " == " + Str + " - " + (string)(Num == Num2)); } void OnStart() { DoubleProperty(99999999.95242); DoubleProperty(0.95242); Print(99999999.95242 == 99999999.952420001); // true Print(0.95242 == 0.95242000000000001); // true }This rule does not work in the debugger yet.
-
Why should I rewrite my answer? What part of my post, that answered your post, was wrong.
-
You may think my posts are Floccinaucinihilipilification, but not everyone thinks like you. (2022)
What @amrali is referring to, is that in previous builds, MetaQuotes improved the display of floating point numbers by rounding/normalising/whatever-you-wish-to-call-it, so as to improve the visual appearance of these numbers in the terminal and debugger. There was however, a build in the past in which this "feature" failed and all the floating point numbers appeared will multiple digits, just like it is happening now in this particular build.
@amrali is aware how floating point numbers work and also about the rounding/normalising issues and has posted quite extensively about it.
What he is asking of you William, is that you consider the context of the issue and the person asking about it, and not just copy/paste a generic answer. Even though your answer was technically correct, it was not really addressing the issue.
I will elaborate a little on @fxsaber answer to emphasize an important feature of the IEEE-754 floating-point format.
Because fp format has a limited number of bits (64 for double, 32 for float), while the real numbers line is infinite, therefore many real numbers (close enough) are actually get encoded to the same binary (hex) value.
As in this case, the numbers 0.95242, 0.952420000000000044, 0.952419999999999998 and many other very close numbers (within a half epsilon, above and below) are encoded as 0x3FEE7A398201CD60 in binary (i.e., many-to-one encoding), and this is unlike the one-to-one encoding of integers. The format guarantees a precise binary representation, for any decimal number as long as it has 17 significant digits or less (the precision). Significant digits or figures is the sum of integer and decimal digits (left and right of the decimal point), excluding leading and trailing zeros. For example, 0.95242,12.345, 9981.2 all have 5 significant figures. But, 1100 has only two sf.
The computer does not know anything about the string representations (0.95242), it sees only the binary. It is the job of the software to convert (translate) that binary into a human readable form.
The software is free to choose which string to display as long as it is round-trips back to the same binary.
So, to display 0x3FEE7A398201CD60 to the user, we can choose the string "0.952419999999999998" (the longest round-trip string) or the string "0.95242" (the shortest round-trip). Both are valid and correct results.
But, if the software converts the above binary to the string 0.9524200000000002 then this means an error, because this string round-trips to the binary 0x3FEE7A398201CD61, which is a different representable fp number.
So, for an optimal display of floating-point numbers:
- The software must output a string that round-trips back to the same numeric value (accurate conversion: binary -> string -> binary).
- It is preferable (NOT a must) to display the shortest round-trippable string.
Number 2, is now a standard in other programming languages like python, C# and JavaScript. They adopt the shortest round-trip string conversion.
Edit:
Before build 3210, MetaQuotes did not conform to rule #1. Both MT4 and MT5 had wrong conversions of double -> string. For example Print(0.95242) => 0.9524200000000002.
But, still they have some issues with rule #2 in build 3566. The display of decimal strings should be unified all over the software (i.e., to be consistent with either the longest or the shortest form).
This is a demo script to display the above numbers in binaries and strings:
#include <math_utils.mqh> // https://www.mql5.com/en/code/20822 #define PRINT(A) Print(#A + " = ", (A)) void OnStart() { double d = 0.95242; Print(d); // examine our fp number PRINT(0.95242); // 0.95242 (what we see is the string representation) PRINT(DoubleToHexadecimal(0.95242)); // 0x3FEE7A398201CD60 (what the computer see is the binary representation) // In real world, we have infinite real numbers very close to 0.95242 (+/- half epsilon). // How to encode them provided that we have only 64 bits ? // They are encoded to the same hex value (i.e., many-to-one encoding), and this is unlike the one-to-one encoding of integers. PRINT(DoubleToHexadecimal(0.952419999999999989)); // 0x3FEE7A398201CD60 PRINT(DoubleToHexadecimal(0.952419999999999998)); // 0x3FEE7A398201CD60 PRINT(DoubleToHexadecimal(0.95242)); // 0x3FEE7A398201CD60 PRINT(DoubleToHexadecimal(0.952420000000000022)); // 0x3FEE7A398201CD60 PRINT(DoubleToHexadecimal(0.952420000000000033)); // 0x3FEE7A398201CD60 PRINT(DoubleToHexadecimal(0.952420000000000044)); // 0x3FEE7A398201CD60 // because these two numbers are encoded to the same binary PRINT(0.95242 == 0.952420000000000044); // true // let's advance to the next representable fp number PRINT(NextAfter(0.95242)); // 0.9524200000000002 PRINT(DoubleToHexadecimal(NextAfter(0.95242))); // 0x3FEE7A398201CD61 // because these two numbers differ in binary by 1 bit (ulp, unit in the last place) // so, they must not be equal (the equal operator == compares the binaries). PRINT(0.95242 == 0.9524200000000002); // false }
Edit:
This function displays the accurate + shortest string for doubles.
MetaQuotes have fixed their double -> string conversion routines starting from build 3210
//+------------------------------------------------------------------+ //| Converting numeric value into the shortest string representation | //| that round-trips into the same numeric value. The result will | //| contain at most 17 significant digits, discarding trailing zeros.| //| The round-trip ("%.17g") format specifier ensures that a numeric | //| value converted to a string is always parsed back into the same | //| numeric value, StringToDouble(Repr(f)) == f. | //| Note: results are consistent with David M. Gay's dtoa.c library. | //+------------------------------------------------------------------+ // toString() string Repr(const double value) { //--- https://stackoverflow.com/a/35708911/4208440 //--- https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/ //--- Try format with 15, 16, 17 significant digits to return the shortest //--- decimal numeric string which round-trips to the specified value. string str = NULL; for(int sig = 15; sig <= 17; sig++) if(value == StringToDouble(str = StringFormat("%.*g", sig, value))) break; return str; } void OnStart() { PRINT(Repr(0.952419999999999998)); // 0.95242 PRINT(0.952419999999999998); // 0.95242 PRINT(Repr(0.95242)); // 0.95242 PRINT(0.95242); // 0.95242 (fixed in build 3210) }
Still, we can print the longest round-trip string, if we would like to:
void OnStart() { //--- the "g" format specifier refers to si[g]nificant digits. PRINT(StringFormat("%.17g", 0.95242)); // 0.95242000000000004 (the longest round-trip) }
So, it all depends on the software implementation that decides which string to show to the user.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am attaching a screenshot of the error.
Open test.mq5 in MetaEditor.
Put a breakpoint on line #6, then run the debugger.
The string() function bug was fixed before in build 3210.
Wrong display of double floating point numbers in Dialog boxes and output of Print(), Alert(), Comment() and FileWrite() functions.
Report: https://www.mql5.com/en/forum/367839/page3#comment_27477157
Fix: https://www.mql5.com/en/forum/367839/page5#comment_27613205 and https://www.metatrader5.com/en/releasenotes/terminal/2226
However, the debugger window of MetaEditor have NOT been fixed yet, as you see in the screenshot.
The debugger must have very precise output with numbers, in order to not to confuse programmers un-aware of this bug.
Actually, the debugger window displays the longest round-trip string, while, Print() and input dialog boxes display the shortest round-trip string. Both are accurate, but the longest-round trip form is confusing and not intuitive.