. um novo e mais completo exemplo para a função de impressão foi acrescentado à ajuda:
voidOnStart()
{
//--- выведем DBL_MAX с помощью Print(), это равносильно PrintFormat(%%.16G,DBL_MAX)Print("---- как выглядит DBL_MAX -----");
Print("Print(DBL_MAX)=",DBL_MAX);
//--- теперь выведем число DBL_MAX с помощью PrintFormat()PrintFormat("PrintFormat(%%.16G,DBL_MAX)=%.16G",DBL_MAX);
//--- Вывод в журнал "Эксперты"// Print(DBL_MAX)=1.797693134862316e+308// PrintFormat(%.16G,DBL_MAX)=1.797693134862316E+308//--- посмотрим как выводится тип floatfloat c=(float)M_PI; // нужно явно приводить к целевому типуPrint("c=",c, " Pi=",M_PI, " (float)M_PI=",(float)M_PI);
// c=3.14159 Pi=3.141592653589793 (float)M_PI=3.14159//--- покажем, что может произойти при арифметических операциях над вещественными типамиdouble a=7,b=200;
Print("---- перед арифметическими операциями");
Print("a=",a," b=",b);
Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
//--- разделим a на b (7/200)
a=a/b;
//--- теперь как будто восстановим значение в переменной b
b=7.0/a; // ожидается, что b=7.0/(7.0/200.0)=>7.0/7.0*200.0=200 - но это не так//--- выведем вновь вычисленное значение bPrint("----- после арифметических операций");
Print("Print(b)=",b);
Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
//--- вывод в журнал "Эксперты"// Print(b)=200.0// Print(DoubleToString(b,16))=199.9999999999999716 (видим, что на самом деле b уже не равно 200.0) //--- создадим очень маленькое значение epsilon=1E-013double epsilon=1 e-13;
Print("---- создадим очень маленькое число");
Print("epsilon=",epsilon); // получим epsilon=1E-013//--- теперь вычтем эпсилон из числа b и выведем снова значение в журнал "Эксперты"
b=b-epsilon;
//--- выводим двумя способамиPrint("---- после вычитания epsilon из переменной b");
Print("Print(b)=",b);
Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
//--- вывод в журнал "Эксперты"// Print(b)=199.9999999999999 (теперь значение b после вычитания эпсилон не может округлиться до 200)// Print(DoubleToString(b,16))=199.9999999999998578// (теперь значение b после вычитания эпсилон не может округлиться до 200)
}
Uma vez que tratou deste assunto, poderia explicar de onde vêm os dígitos extra, eles estão marcados a vermelho.
Pensei apenas anteriormente que para IEEE 754 o número de dígitos significativos não pode exceder 17, e não após o ponto decimal, mas todos.
arithmetic formats: sets of binary and decimal floating-point data, which consist of finite numbers (including signed zeros and subnormal numbers), infinities, and special "not a number" values (NaNs) interchange formats: encodings (bit strings) that may be used to exchange floating-point data in an efficient and compact form rounding rules...
Esta é a função que gera dígitos significativos desnecessários. Não deve haver nenhum.
Tem de dobrar a DoubleToString? :) Mais uma vez, sem reclamar nada: o Manual diz literalmente o seguinte:
"Se o valor dos dígitos estiver no intervalo de 0 a 16, a representação em cadeia do número será recuperada com o número especificado de casas decimais. Se o valor dos dígitos estiver entre -1 e -16, então será obtida uma representação em cadeia do número em formato científico com o número de casas decimais especificado. Em todos os outros casos, a cadeia de números terá 8 casas decimais".
Especificou um valor de 30. De acordo com a descrição no Manual de Referência, o valor da cadeia do número deve ter 8 casas decimais, neste caso.
Vá ao seu perfil e seleccione Service Desk
. um novo e mais completo exemplo para a função de impressão foi acrescentado à ajuda:
Uma vez que tratou deste assunto, poderia explicar de onde vêm os dígitos extra, eles estão marcados a vermelho.
Pensei apenas anteriormente que para IEEE 754 o número de dígitos significativos não pode exceder 17, e não após o ponto decimal, mas todos.
Costumava apenas pensar que para IEEE 754 o número de dígitos significativos não pode exceder 17, e não o ponto decimal, mas o total.
Honestamente, isso nunca me incomodou. Mas aqui estão alguns links, se estiver interessado:
Não garanto que haverá respostas a estas perguntas, mas podem ser interessantes de ler.
Honestamente, isso nunca me incomodou.
Deve haver algo de errado com a função DoubleToString.
Teste (EURUSD,D1)66666666.666666666666278616
Esta é a função que gera dígitos significativos desnecessários. Eles não deveriam estar presentes.
Deve haver algo de errado com a função DoubleToString.
Teste (EURUSD,D1)66666666.666666666666278616
Esta é a função que gera dígitos significativos desnecessários. Não deve haver nenhum.
Tem de dobrar a DoubleToString? :) Mais uma vez, sem reclamar nada: o Manual diz literalmente o seguinte:
"Se o valor dos dígitos estiver no intervalo de 0 a 16, a representação em cadeia do número será recuperada com o número especificado de casas decimais. Se o valor dos dígitos estiver entre -1 e -16, então será obtida uma representação em cadeia do número em formato científico com o número de casas decimais especificado. Em todos os outros casos, a cadeia de números terá 8 casas decimais".
Especificou um valor de 30. De acordo com a descrição no Manual de Referência, o valor da cadeia do número deve ter 8 casas decimais, neste caso.
Tem de duplicar o ToString? :) Mais uma vez, sem reclamar nada: o Manual de Referência diz literalmente o seguinte:
Tem um valor de 30. A julgar pela descrição no Manual de Referência, um valor de cadeia de um número neste caso deve conter 8 casas decimais.
O livro de referência também tem um sinal de menos neste local :)
Copiei-o a partir daqui: https://www.mql5.com/ru/docs/convert/doubletostring
A frase que sublinhei, "Em todos os outros casos, o valor da cadeia do número terá 8 casas decimais" não parece conter um sinal de menos :/
E a palavra sublinhada na frase é redundante. :)
A minha pergunta perdeu-se.
https://www.mql5.com/ru/forum/1111/page721#comment_179003
O mandado ainda está pendurado.