Características da linguagem mql5, subtilezas e técnicas - página 158

 

Existe uma matriz, preenchida tanto com valores grandes, cerca de 10e60, como pequenos, como 1e-40. E há um código como este

      for(k=-16;k<=16;++k)
      {
        double Tmp1=(double)(DoubleToString(Matrix[i][j],k));
        double Tmp2=(double)((string)Matrix[i][j]);
        if(Tmp1==Tmp2)
          break;
      }
Em cerca de 27% dos casos k=-15. Em outros casos k=-16. Daí uma pergunta: existe alguma forma de substituir a operação(string)Matrix[i][j] por uma função de conversão mais rigorosa? Ou talvez haja uma função que corta algumas das casas decimais? NormalizeDouble não é correcto, truncará 1,12345678e-40 em 0. Quero que trunque após o ponto decimal. Ou a conversão para (string) tem a sua própria vida e não pode ser expressa através de funções? Obrigado.
 
traveller00:

Módulo de Diferença.

 
fxsaber:

O módulo da diferença.

Poderia ser um pouco mais específico? Talvez com um exemplo de código? Diferença entre o quê e o quê?

A questão é que essa dupla conversão(dupla)((string)Matrix[i][j]); truncará um número incontrolável de caracteres após o ponto decimal. Gostaria de manter esta truncagem, por um lado = poder repeti-la, e por outro lado este número de caracteres é controlado.

 
traveller00:

Poderia ser um pouco mais específico? Talvez com um exemplo de código? Diferenças entre o quê e o quê?

if (MathAbs(Value1 - Value2) < Epsilon)
 

Ah, estou a ver o seu ponto de vista. Não, a questão é um pouco diferente. A comparação aqui é apenas como um exemplo para mostrar que não podemos substituir a conversão via (double)((string)Matrix[i][j]); pela conversão via DoubleToString. Na realidade, a tarefa em mãos não é uma comparação. É antes uma certa reposição de precisão através dessa dupla conversão. Por um lado quero ser capaz de repetir o recorte via (cordel), por outro lado quero ser capaz de controlar a precisão do recorte como o DoubleToString faz.

E como pergunta secundária, será que estas conversões são feitas de forma diferente e vivem as suas vidas separadas e não relacionadas?

 
traveller00:

Ah, estou a ver o seu ponto de vista. Não, a questão é um pouco diferente. A comparação aqui é apenas como um exemplo para mostrar que não podemos substituir a conversão via (double)((string)Matrix[i][j]); pela conversão via DoubleToString. Na realidade, a tarefa em mãos não é uma comparação. É antes uma certa reposição de precisão através dessa dupla conversão. Por um lado quero ser capaz de repetir o recorte via (cordel), por outro lado quero ser capaz de controlar a precisão do recorte como o DoubleToString faz.

E como nota secundária, pergunto-me se estas conversões são feitas de forma diferente e vivem as suas vidas separadas e não relacionadas.

Não percebo porque é que a NormalizeDouble e aDoubleToString não osatisfazem, eles têm alguma precisão que você quer, ou você quer alguma precisão, mas não sabe o que é?

 

Concordo que a tarefa não é totalmente transparente. Porque estou a tentar montar uma espécie de muleta para os testes.

Digamos que existe um número 1.0123456789e-50. Preciso de o arredondar com alguma precisão para que isso aconteça:

1. Por defeito, funciona como uma dupla conversão via(string).

2. a precisão pode ser controlada, se desejado.

Assim,NormalizeDouble não é adequado, irá simplesmente anular este número. E a DoubleToString não permite repetir o resultado do passo 1.

O problema cresce a partir da pergunta seguinte. Como escrevi acima, existe uma matriz. O inverso desta matriz é calculado. Por vezes (talvez devido a erros devido a limitações de precisão do dobro), a matriz revela-se degenerada e o inverso não pode ser calculado. Mas se se cortar um pouco a precisão, ainda será capaz de calcular o inverso. É por isso que queria fazer alguns testes e obter algumas estatísticas em que medida o resultado é semelhante ao verdadeiro. A dupla conversão via (cordel) resolve o problema na maioria dos casos. Mas por vezes não é suficiente e eu gostaria de poder controlar a precisão do corte. E a DoubleToString, mesmo com uma precisão de -16 a 16, não resolve o problema na maioria dos casos.

 

Pode dizer-me, por favor, pls.

No indicador a ordem das séries, por exemplo fechar[], é definida pelo ArraySetAsSeries() uma vez ou de alguma outra forma ?

É feito em OnCalculate() ou em OnInit() ?

Encontrei uma situação confusa:

Encomendar no fim[], definido por AS_SERIES na entrada no primeiro tick, no tick seguinte muda espontaneamente para normal, ou seja !AS_SERIES.

Não encontrei qualquer razão para fazer isto no código.

 
Yurixx:

Pode dizer-me, por favor, pls.

No indicador a ordem das séries, por exemplo fechar[], é definida pelo ArraySetAsSeries() uma vez ou de alguma outra forma ?

É feito em OnCalculate() ou em OnInit() ?

Encontrei uma situação confusa:

Encomendar no fim[], definido por AS_SERIES na entrada no primeiro tick, no tick seguinte muda espontaneamente para normal, ou seja !AS_SERIES.

Ainda não encontrei a razão para isso no código.

E não verá a matriz de fechamento[] no OnInit(). E nenhum de outros parâmetros OnCalculate() predefinidos.

Daí a conclusão - apenas em OnCalculate().

 
Artyom Trishkin:

E no OnInit() não se verá de perto[] a matriz. E nenhum dos outros parâmetros OnCalculate() pré-definidos.

Daí a conclusão - apenas em OnCalculate().

Cheguei à mesma conclusão. )))

Resta saber se a definição desta ordem uma vez é suficiente ou se deve ser feita em cada carraça.