Valor de una variable double de solo dos decimales siempre.

 
Hola a toda la gente programadora en mql4. Haciendo mi propio EA se me presento un problema para calcular valores exactos... pongo un ejemplo de código para que se entienda desde el principio y entre todos podamos no solo encontrar la solución sino el porqué del problema...
 
int start()
   {
   double resultado = 7.00 / 100.00 ;
   Comment(" Resultado "+(string)resultado);
   return(0);
   }
 

el resultado de esto es: 0.07000000000000001

Saludos.

 
#property strict
int OnStart()
{
   double dbResultado = 7.0 / 100.0;
   string sResultado  = DoubleToString( dbResultado, 2 );
   Print( "Resultado = ", sResultado );
   return 0;
};
2023.05.12 01:33:00.478 test EURUSD,H1: Resultado = 0.07

MQL4 (English):

DoubleToString

Converting a numeric value to a text line with a specified accuracy

Conversion Functions

MQL5 (Español):

DoubleToString

Conversión del valor numérico a una cadena de caracteres con una precisión especificada

Conversión de datos

DoubleToString - Conversion Functions - MQL4 Reference
DoubleToString - Conversion Functions - MQL4 Reference
  • docs.mql4.com
DoubleToString - Conversion Functions - MQL4 Reference
 

Gracias Fernando por responder tan rápido, se agradece de verdad pero el asunto acá no es modificar una variable double a string sino que la variable double ya tenga el valor que quiero darle, o sea que siempre sea de dos decimales, por ejemplo: 0.00 o 4.00 o 0.07 Sé que suena simple pero es aún más complejo de lo que parece.

Te invito a que hagas un ejercicio conmigo y entiendas a lo que voy. Te paso un código para que lo pruebes en el strategy tester y veas que con los números del int z 7;56;69;81;94;etc... el resultado te arroja más de dos decimales.

#property strict

int z=0;

int start()
   {
   z++;
   double resultado=(z/100.00);
   Comment(" z "+(string)z+"\n"+" suma "+(string)resultado);
   return(0);
  }
 

(traducido automáticamente del inglés)

Eso no es posible. Un "double" es un número binario, no un número decimal. No puede tener un número exacto de posiciones decimales.

Aquí hay algunas referencias del foro en inglés...

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias comerciales

MathRound falla para un número en particular

Fernando Carreiro , 2018.01.01 22:08

Quiere decir que el valor "0.69" no se puede representar exactamente dada la forma en que funciona un número de punto flotante (basado en una representación binaria y no decimal); por lo tanto, el valor se representa como "0.68999999..." (ver más abajo).

Realmente nunca se puede "normalizar" y es la razón principal por la que tanto @whroeder1 como yo cuestionamos el uso de la función NormalizeDouble() . Como mínimo, debería cambiarse el nombre a algo así como "RoundDigits()" porque es más una función de "redondeo" y no "normaliza" de ninguna manera.


https://www.h-schmidt.net/FloatConverter/IEEE754.html

EDITAR: tenga en cuenta que las imágenes anteriores son ejemplos de representación en el "flotante" de 4 bytes, y no en el "doble" de 8 bytes que ofrece más precisión pero aún no puede representar el valor "0.69" exactamente debido al "binario "naturaleza del formato.

EDIT2: Para futuros lectores que tienen dificultad para entender (o aceptar) este concepto, de valores decimales que no tienen una representación exacta con un "flotante" o un "doble", aquí hay un artículo que vale la pena leer:

Why 0.1 Does Not Exist In Floating-Point

Many new programmers become aware of binary floating-point after seeing their programs give odd results: “Why does my program print 0.10000000000000001 when I enter 0.1?”; “Why does 0.3 + 0.6 = 0.89999999999999991?”; “Why does 6 * 0.1 not equal 0.6?” Questions like these are asked every day , on online forums like stackoverflow.com .

The answer is that most decimals have infinite representations in binary. Take 0.1 for example. It’s one of the simplest decimals you can think of, and yet it looks so complicated in binary:


Decimal 0.1 In Binary ( To 1369 Places

The bits go on forever; no matter how many of those bits you store in a computer, you will never end up with the binary equivalent of decimal 0.1.

... Read the rest of the article at: http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

NormalizeDouble - Conversion Functions - MQL4 Reference
NormalizeDouble - Conversion Functions - MQL4 Reference
  • docs.mql4.com
NormalizeDouble - Conversion Functions - MQL4 Reference
 

Gracias por responder Fernando y sobre todo por compartir información, esto lo explica todo, me ayudó a entender con más profundidad este tema.

Uno de mis grandes problemas era que al calcular con variables double al final de un cierto tiempo, corriendo mi EA en el Strategy Tester, el resultados empieza a cambiar en céntimos desigual a AccountBalance().

La solución que encontré más viable es multiplicar cada variables double por cien y pasar a trabajar con variables int e imaginar un punto antes de los dos últimos números del resultado.

Saludos.

Razón de la queja: