Paradoja de NormalizarDoble

 

¡Buenas tardes!

Por más que leo esta sección de Ayuda, sigo sin entender de dónde sale ese 1 fraccionario del final.

Tenga en cuenta que cuando un número normalizado se imprime en el Diario utilizando Print(), puede contener más decimales de los que espera. Por ejemplo,

doble a=76.671;// número normalizado con 3 decimales
Print("Print(76.671)=",a);// imprimirlo tal cual
Print("DoubleToString(a,8)=",DoubleToString(a,8));// imprimirlo con la precisión especificada

se emite en la terminal:

DoubleToString(a,8)=76.67100000
Print(76.671)=76.67100000000001

 
transcendreamer:

¡Buenas tardes!

Por más que leo esta sección de Ayuda, sigo sin entender de dónde sale ese 1 fraccionario del final.

Tenga en cuenta que cuando un número normalizado se envía a Journal utilizando Print(), puede contener más decimales de los que espera. Por ejemplo,

doble a=76.671;// número normalizado con 3 decimales
Print("Print(76.671)=",a);// imprimirlo tal cual
Print("DoubleToString(a,8)=",DoubleToString(a,8));// imprimirlo con la precisión especificada

se emite en la terminal:

DoubleToString(a,8)=76.67100000
Print(76.671)=76.67100000000001

El tipo doble tiene limitaciones de precisión debido a que pueden producirse errores.

Recomiendo este artículo: https://www.mql5.com/ru/articles/1561

Особенности работы с числами типа double в MQL4
Особенности работы с числами типа double в MQL4
  • 2009.11.02
  • MetaQuotes Software Corp.
  • www.mql5.com
В данной заметке собраны советы по решению наиболее часто возникающих ошибок при работе с числами типа double в программах на MQL4.
 
ENSED:

El tipo doble tiene limitaciones en cuanto a la precisión, lo que puede dar lugar a errores.

Recomiendo este artículo: https://www.mql5.com/ru/articles/1561

Veo la recomendación, gracias.

Se puede utilizar DoubleToStr cuando se emite

¡pero no está claro de dónde viene ese en primer lugar!

Si estuviera haciendo una división/multiplicación, está bien, es un error.

¿Pero en una constante? ¿La que yo mismo receté?

Resulta que tengo que utilizar el redondeo para una constante que inicialmente no tiene esta precisión

y, lo que es más importante, ¡la confianza en lo que realmente se almacena en la doble variable se ve socavada!

 

Cita de la documentación

Необходимо помнить, что вещественные числа хранятся в памяти компьютера с некоторой ограниченной точностью в двоичной системе счисления, в то время как общепринятой в использовании является десятичная система счисления. Поэтому многие числа, которые точно записываются в десятичной системе, в двоичной системе можно записать только в виде бесконечной дроби.

Por ejemplo, los números 0,3 y 0,7 se representan en el ordenador como fracciones infinitas, mientras que el número 0,25 se almacena exactamente como una potencia de dos.

 
stringo:

Cita de la documentación

interesante...

Ya estoy adivinando que no está en MQL sino en algún lugar más profundo, a nivel de las normas de los 80

pero sigue siendo muy extraño...

No lo he visto en ningún otro idioma de aplicación

sería razonable tener algunas soluciones en el nivel del lenguaje MQL

 

y sigue sin explicar por qué el código de abajo da 0000000001 colas

current=NormalizeDouble(GlobalVariableGet("Equity-"+portfolio_id),2);

text = "Positions closed at " + (string)current + " for portfolio: " + portfolio_name;

if(!automatic) MessageBox(text,""); else Print(text);

porque hice la normalización

y el número sigue siendo de cola.

 
transcendreamer:

interesante...

Ya estoy adivinando que no se trata de MQLs sino de algún lugar más profundo al nivel de los estándares de los 80

pero sigue siendo muy extraño...

No he visto esto en ningún otro idioma de aplicación

sería razonable tener algunas soluciones a nivel de MQL

¿Qué tiene de difícil?

Si necesita una precisión de hasta 4 dígitos. Multiplica el número por 10000, descarta la parte fraccionaria y divide por 10000.

Las funciones matemáticas de mql se pueden encontrar en la documentación.

 

text = "Posiciones cerradas a " + (cadena)actual + " para la cartera: " + nombre_cartera;

DoubleTo String para la corriente y estará bien

 

Sí, ya me he dado cuenta de que hay que forzar el redondeo

NormalizeDouble aparentemente no hace el trabajo

 
transcendreamer:

Sí, ya me he dado cuenta de que hay que forzar el redondeo

NormalizeDouble no parece hacer el trabajo

NormalizeDouble es exactamente como funciona (y siempre ha funcionado así, desde el primer MQL)

Un número se multiplica por 10 a la potencia de los dígitos, se convierte en forma de entero (descartando la parte fraccionaria), y luego se divide por 10 a la potencia de los dígitos

¿Cuál es el problema? ¿Romper el patrón?

 
stringo:

NormalizeDouble funciona exactamente así (y siempre ha funcionado así desde el primer MQL)

El número se multiplica por 10 a la potencia de los dígitos, se convierte en forma de número entero (descartando la parte fraccionaria), y luego se divide por 10 a la potencia de los dígitos

¿Cuál es el problema? ¿Romper el patrón?

Un patrón de ruptura es que, incluso después de la normalización, ¡hay colas!