Pergunta para os mestres da MQL4. Novamente sobre Double Compare. - página 7

 
SK. писал (а):

Esta conversa parece durar indefinidamente. Quando um novo usuário adquire a experiência e o conhecimento adequados, ele normalmente tem tempo para esbarrar várias vezes na normalização.

Talvez em MT5 faça sentido limitar à força a precisão dos números reais ao realizar operações de comparação, digamos, a 8 casas decimais (ou seja, executar à força NormalizeDouble() com dígito=8).

Eu não esperaria isso de você. Absolutamente não!
Se a operação de comparação for usada repetidamente (em cálculos recorrentes, etc.), então arredondando para 8 dígitos na entrada, o erro de saída pode ser proporcional a 1.

Tive tal experiência com o cálculo do SmoothedAvarege, calculando-o em minha aplicação há um ano. Depois disso, estou tentando escolher tais métodos de trabalho que não afetem a capacidade de dígitos de duplas.
Ou, como a gravidade001 sugeriu, mudar para a INTam (que, como você entende, é muito demorada).
 
SK. писал (а):

Talvez em MT5 faça sentido limitar à força a precisão dos números reais ao realizar operações de comparação a, digamos, 8 casas decimais (ou seja, realizar à força NormalizeDouble() com dígito=8).


Entretanto, não apenas as operações definidas pelo usuário tornam o terminal mais lento, mas também as operações ocultas a ele. Parece-me preferível simplesmente introduzir a função ComparePrice no idioma. A propósito, assim como Irtron, considero o Ponto/2 uma medida natural (talvez melhor Ponto *0,5). Para evitar a divisão/multiplicação toda vez, esta metade pode ser feita uma variável pré-definida. Até que isso não exista, você mesmo pode digitar tal variável e calculá-la uma vez no início do início. Embora os desenvolvedores possam fazer uma função de comparação dupla com precisão predefinida, ou seja, a mesma, mas com dígitos em vez do Ponto/2.
 
Depfy:

Você fez uma bagunça... :)

A comparação dos números flutuantes é feita comparando o módulo de diferença com um pequeno limiar.

Retorno (fabs(d1-d2) < 1e-10) por exemplo.

De que adianta baralhar as águas... A função NormalizeDouble(...) é apenas para relatórios de boa aparência.

Obrigado pelo exemplo.
Mas você está perdendo o ponto, precisa ler com mais atenção. A essência da questão é o estilo de programação em geral, e no caso específico do MT4.
 
VBAG:
Depfy:

Você fez uma bagunça... :)

A comparação dos números flutuantes é feita comparando o módulo de diferença com um pequeno limiar.

Retorno (fabs(d1-d2) < 1e-10) por exemplo.

De que adianta baralhar as águas... A função NormalizeDouble(...) é apenas para relatórios de boa aparência.

Obrigado pelo exemplo.
Mas você está perdendo o ponto, precisa ler com mais atenção. A essência da questão é o estilo de programação em geral, e no caso específico do MT4.

É melhor você nos dizer qual é o objetivo desta pergunta. Caso contrário dicas - Eu não entendo :)

Se estamos falando de velocidade, os processadores modernos realizam operações de ponto flutuante

quase tão rápido quanto os números inteiros. Quanto a STYLE, desculpe, regras de pragmatismo...

Quando há ASHIPS, de que tipo de estilo estamos falando... Desde que funcione. ...

Caso contrário, não há outro problema além de comparar dois números: ))))))))

 
VBAG:
Eu não esperava nada parecido de você. Você não deve fazer isso em nenhum caso!
Se a operação de comparação for usada repetidamente (em cálculos recorrentes, etc.), então se você arredondar até 8 dígitos na entrada, o erro de saída pode ser proporcional a 1.

Tive tal experiência com o cálculo do SmoothedAvarege, calculando-o em minha aplicação há um ano. Depois disso, estou tentando escolher tais métodos de trabalho que não afetem a capacidade de dígitos de duplas.
Ou, como a gravidade001 sugeriu, mudar para a INTam (que, como você entende, é muito demorada).


Espere um minuto. Não há necessidade de tirar conclusões precipitadas.

Em primeiro lugar. Não me proponho a arredondar à força o valor real da variável real em si. Proponho forçar o arredondamento dos valores comparados (cópias) das variáveis ao calcular o resultado de uma operação de comparação (para o caso padrão). E, claro, o valor real de uma variável não deve ser tocado. Neste caso, nenhum outro valor calculado seria afetado, pois os valores originais das variáveis utilizadas nas operações de comparação retêm seus valores, e os erros nos cálculos cíclicos não se acumulariam.

Segundo. Eu disse que, para eliminar erros com conseqüências mais duras, podemos ir por aqui. Entretanto, a fim de fornecer também cálculos mais exigentes, é necessário preservar a possibilidade de utilizar a funçãoNormalizeDouble() com parâmetros especificados.

Portanto, minha sugestão não limita as capacidades do idioma, mas as amplia.

Entretanto, levando em conta que em operações de comparação, como regra, são utilizados valores de preço (isto é, dígito = 4), na grande maioria dos casos, este erro simplesmente não ocorrerá. Assim, a utilização da tecnologia proposta reduzirá o número de erros que levam a conseqüências imprevisíveis.

 
lna01:
E enquanto isto não estiver disponível, você pode digitar tal variável e calculá-la uma vez no primeiro início de partida.

Você não pode.

Ou melhor, você pode escrever strings do programa, mas ninguém (incluindo os desenvolvedores) irá garantir que o valor desta variável permanecerá estritamente inalterado durante toda a vida da EA. Não se trata da precisão do código do programa, mas das características tecnológicas dos cálculos e das regras tecnológicas para armazenar os valores das variáveis. Se não fosse assim, este problema nem sequer existiria.

Na situação atual, o valor inicial de 123,00000000000 variável pode aparecer como 122,999999999999999999 no momento em que é utilizado nos cálculos. Isto apesar do fato de que o valor da variável nunca ter mudado desde que foi criada e só foi chamada pelo programa para participar de outros cálculos.

Na verdade, foi por isso que houve todo esse alvoroço. É por isso que criamos a necessidade de utilizar NormalizeDouble() o mais próximo possível do cálculo real, de preferência diretamente na condição de se, para, enquanto declarações.

 
SK. писал (а):
lna01:
E enquanto isso não estiver disponível, você mesmo pode digitar tal variável e calculá-la uma vez no primeiro início de partida.

Você não pode.

Ou melhor, você pode escrever strings do programa, mas ninguém (incluindo os desenvolvedores) irá garantir que o valor desta variável permanecerá estritamente inalterado durante toda a vida da EA. Não se trata da precisão do código do programa, mas das características tecnológicas dos cálculos e das regras tecnológicas para armazenar os valores das variáveis. Se não fosse assim, este problema nem sequer existiria.

Na situação atual, o valor inicial de 123,00000000000 variável pode aparecer como 122,999999999999999999 no momento em que é utilizado nos cálculos. Isto apesar do fato de que o valor da variável nunca ter mudado desde que foi criada e só foi chamada pelo programa para participar de outros cálculos.

Na verdade, foi por isso que houve todo esse alvoroço. É por isso que eu precisava usar NormalizeDouble() o mais próximo possível do cálculo real, de preferência na condição de se, para, enquanto declarações.

Caramba, acho que estou começando a entender o porquê de tanto alarido...

Em resumo, acho que não tenho que inventar nada. Tudo depende da situação. Qual é o objetivo? Se dois números podem diferir em mantissa 0,1, e se for CRÍTICO, é uma coisa, se não for importante, é outra. Depende do que está sendo comparado entre si. Mas a FLEXIBILIDADE, dada por um compilador REAL sem folhos, é uma coisa REAL e necessária, IMHO.

:)

 
SK. писал (а):
A questão aqui não é a precisão do código do programa, mas as características tecnológicas dos cálculos e as regras tecnológicas para o armazenamento de valores variáveis. Se não fosse por isso, a questão não teria surgido.
É verdade sobre os cálculos, mas me pareceu que tudo deve ser melhor com o armazenamento. E quando os dígitos = 4, a diferença no 15º dígito não deve desempenhar um papel.
 
Depfy:

Caramba, acho que estou começando a ver o porquê de tanto alarido...

De modo geral, não creio que haja NADA a ser inventada. Porque tudo depende da situação específica. Qual é o objetivo? Se dois números podem diferir em mantissa 0,1, e se for CRÍTICO, é uma coisa, se não for importante, é outra. Depende do que está sendo comparado entre si. Mas a FLEXIBILIDADE, dada por um compilador REAL sem folhos, é uma coisa REAL e necessária, IMHO.

:)


Eu não posso responder sobre "inventar". Aparentemente, depende do que se deve pensar:)

Por exemplo, em alguns casos, invenções como o Point/2 realmente permitem fazer cálculos com alguma precisão. No entanto, é melhor usar a recomendação dos desenvolvedores, ou seja, de uma vez por todas (até nova documentação) para tomar como regra usar a função NormalizeDouble() ao calcular operações de comparação.

 
lna01:
SK. escreveu (a):
A questão aqui não é a precisão do código do programa, mas as características tecnológicas dos cálculos e as regras tecnológicas para o armazenamento de valores variáveis. Se não fosse por isso, a questão não teria sequer surgido.
Isso é verdade para os cálculos, mas eu achei que deveria ser melhor para o armazenamento. E com os dígitos = 4, a diferença no 15º dígito não deve importar.

Não importa se você usa o NormalizeDouble(). E se você não a usa, é uma questão de sorte.