Erros, bugs, perguntas - página 719

 
ALozovoy:

Vá ao seu perfil e seleccione Service Desk


Obrigado
 
Rosh:

. um novo e mais completo exemplo para a função de impressão foi acrescentado à ajuda:

void OnStart()
  {
//--- выведем 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
 
//--- посмотрим как выводится тип float
   float 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 - но это не так
//--- выведем вновь вычисленное значение b
   Print("----- после арифметических операций");
   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-013
   double 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.

 
victorg:

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.

IEEE floating point - Wikipedia, the free encyclopedia
  • en.wikipedia.org
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...
 
Rosh:

Honestamente, isso nunca me incomodou.

Deve haver algo de errado com a função DoubleToString.

void OnStart()
  {
  double a=2000000.0/3.0;
  Print(DoubleToString(a,30));
  }

Teste (EURUSD,D1)66666666.666666666666278616

Esta é a função que gera dígitos significativos desnecessários. Eles não deveriam estar presentes.

Документация по MQL5: Преобразование данных / DoubleToString
Документация по MQL5: Преобразование данных / DoubleToString
  • www.mql5.com
Преобразование данных / DoubleToString - Документация по MQL5
 
victorg:

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.

 
Yedelkin:

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 Manual tem também um sinal de menos neste local :)
 
Во всех остальных случаях число строковое значение числа будет содержать 8 знаков после запятой".
E a palavra sublinhada na frase é redundante. :)
 
Rosh:
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 :/

Документация по MQL5: Преобразование данных / DoubleToString
Документация по MQL5: Преобразование данных / DoubleToString
  • www.mql5.com
Преобразование данных / DoubleToString - Документация по MQL5
 
tol64:
E a palavra sublinhada na frase é redundante. :)
Bem, há que tempos :)
 

A minha pergunta perdeu-se.

https://www.mql5.com/ru/forum/1111/page721#comment_179003

O mandado ainda está pendurado.