Erros, bugs, perguntas - página 2821

 
Igor Makanu:

a normalização não é arredondada

Eu tenho um A+ em teoria, como trabalhar com o dobro e assim por diante. O algoritmo NormalizeDouble contém um erro. O tema levantado está apenas indirectamente relacionado com a comparação de duplas.

 
fxsaber:

Repito a minha pergunta.

A imagem mostra o valor da variável não normalizada n e da variável normalizada m e como são diferentes. Mas se quiser comparar tangas, essa é a sua preferência.

fxsaber:

Conheço a teoria, como trabalhar com o dobro e coisas do género numa escala A+. O algoritmo NormalizeDouble contém um erro. O tema levantado está apenas indirectamente relacionado com a comparação de duplas.

Definitivamente não pode passar sem essa explicação da Semko aqui.
 
NormalizeDouble é apenas um certo algoritmo que se aplica a um número duplo. Infelizmente, há um erro. Se corrigido, o erro desaparecerá. A dupla representação de todas as outras não se alterará de forma alguma.
 
fxsaber:

O algoritmo NormalizeDouble contém um erro.

sim

Penso que o A100 escreveu sobre isso

mas os criadores desde a MQL têm-se agarrado a esta "característica", infelizmente


fxsaber:
Se o corrigirem, o erro desaparecerá.
Penso que haverá outros insectos e haverá muito ruído ))))
 
Igor Makanu:

Penso que aparecerão outros bugs e haverá muito ruído ))))

Não o farão, porque quase todos comparam até mesmo as dobras normalizadas através da normalização. Ou seja, colocam-no onde quiserem.


A normalização adequada deve ser sempre verdadeira nesta condição.

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Erros, bugs, perguntas

fxsaber, 2020.08.10 11:37

  Print((double)(string)Norm == Norm);    // false

Esta é a única verificação de que a normalização está correcta. Se der sempre verdade, nada se quebrará.

 
fxsaber:
NormalizeDouble é apenas um certo algoritmo que se aplica a um número duplo. Infelizmente, há um erro. Se corrigido, o erro desaparecerá. Todas as outras duplas representações não mudarão em resultado disso.
Penso que não se trata da função, mas que as constantes não são normalizadas pelo compilador (embora devam ser).
O mesmo se aplica à conversão de cordel para o dobro.
 
Alexey Navoykov:
Penso que não se trata da função, mas que as constantes não são normalizadas pelo compilador (embora devam ser).
O mesmo se aplica ao cordel para dupla conversão.

Então as mesmas constantes em DLL e MQL não corresponderão.

 
fxsaber:

Então as mesmas constantes em DLL e MQL não corresponderão.

Também é verdade. Além disso, qualquer normalização é uma perda de precisão, pelo que posso ter ido longe demais com a normalização das constantes.
Em geral, este problema, na minha opinião, não tem uma solução inequívoca. Embora na realidade não seja um problema desse tipo.
 
Alexey Navoykov:
Também é verdade. Além disso, qualquer normalização é uma perda de precisão, por isso provavelmente estou a exagerar com uma normalização constante.
Em geral, este problema não me parece ter uma solução inequívoca, embora, na sua essência, não seja um tal problema.

Basta afinar o actual algoritmo de normalização.

 
fxsaber:

Basta afinar o actual algoritmo de normalização.

void OnStart() {
   double d1=1.79435;
   double d2=NormalizeDouble(1.79435,5);
   Print(d1==d2);
   Print(is_equal(d1,d2,_Point/2));
}
//+------------------------------------------------------------------+
bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}

Nem sequer sei se se trata de um bug no algoritmo.
Realmente, não se podem comparar as duplas. Apenas uma regra difícil.
Ou, como diz Slava, através do epsilon ou através da multiplicação (por exemplo, por 1/_Ponto) com conversão para int com arredondamento.

Apenas o arredondamento não é feito utilizando a ronda(), ceil(), chão() padrão, uma vez que também devolvem o dobro.

Ou através destes, especialmente porque trabalham mais rapidamente do que os normais:

int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;}
int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;}

Mais fácil e mais rápido, é claro, através do epsilon:

bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}