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

 
SK. писал (а):
VBAG:
Eu não esperaria isso de você.

Retiro o que disse.
Ainda bem que eu estava errado em minhas dúvidas.
 

PARA SK.

Você é quem melhor sabe. Eu não considero a MQL uma linguagem de programação. É um tal DIALETO.

A propósito, estou farto de duas coisas nele:

1) nenhuma enumeração de operações, ou seja, parênteses curvos

2) voltar - você está terrivelmente cansado de parênteses.

No geral, muito bem feito, pessoal.

Kernighan e Ritchie - uma salva de palmas para eles.

 
VBAG писал (а):
Retiro o que disse.
Ainda bem que eu estava errado em minhas dúvidas.


Não tivemos nenhuma discussão :)

Depfy:

Eu não considero a MQL como uma linguagem de programação. É um tal DIALETO.

É provavelmente uma questão de terminologia. Eu, por exemplo, encontro na MQL todos os atributos de um idioma completo. De qualquer forma, é uma das poucas línguas (notavelmente, a melhor), que permite aos comerciantes mecanizar e automatizar suas atividades. Acho que esta língua é bastante satisfatória, pelo menos no sentido de que suas possibilidades muitas vezes excedem as necessidades da maioria dos algoritmos (em outras palavras - se houvesse idéias bem pensadas, e os meios para sua implementação já estivessem disponíveis).
 
SK. писал (а):
...

Na situação atual, o valor inicial da variável 123.00000000000 pode ser 122.999999999999999999 no momento em que ela for utilizada nos cálculos. E isto apesar do fato de que, desde que a variável foi descoberta, seu valor nunca mudou, mas somente foi solicitado pelo programa para participar de outros cálculos.


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

Você tem certeza do que está dizendo? Se você puder especificar a fonte de seus conhecimentos?

Então eu tenho esta pergunta para você.

1? se o problema é lembrar ou ler uma variável, como a NormalizeDouble() pode ajudar se o valor de retorno também é lembrado ou lido com um erro?
2? por que o esquema NormalizeDuplo(valor, dígitos) !OC! NormalizeDuplo(valor, dígitos), onde !OC! - operador de comparação, não funciona sempre? mesmo que seja inserido diretamente no se?
3? Você sabe como funciona o NormalizeDouble() (algoritmo de função)?
4? eu escrevi minha opinião sobre isso, o que você acha ?

gravidade001 escreveu (a):

...
Já lhe falei sobre a normalização. Primeiro me diga por que você precisa aplicá-lo e depois como e onde.

Essa é a pergunta chave, não é? Há muito tempo eu mesmo venho pensando nisso: "você entra o dobro e ganha o dobro ". O que poderia mudar?
Ainda não encontrei a resposta exata. Mas eu imagino que seja assim

duplo a = 2.000000000000
duplo b = 2.000000000001
duplo c = 1,99999999999999

Todas estas variáveis são diferentes e são armazenadas na memória com precisão até o último dígito!
Neste caso, nós mesmos definimos os sinais (dígitos). Tudo o que não é definido é preenchido com zeros.

Se tivéssemos definido o dobro a = 2,0, e ele é armazenado na memória como 2,0000001 ou 1,9999999, é claro que NormalizeDouble() não ajudaria, pois devolveria um valor impreciso!
Acho que tal erro ocorre quase nunca ao memorizar um valor variável. Além disso, não acho que o número 2.0 seja armazenado como 1.9999999999999999999 de propósito, já que cada caractere (dígito ou ponto) é armazenado com um bit específico no fio de bits! Portanto, o número 2.0 é armazenado com segurança como 2.00000...00.

O outro caso é quando nós mesmos não determinamos os sinais:

a = 4.0;
b = 2.0;
c = a / b // - a operação de "divisão" é feita pelo processador, ou melhor, pelo co-processador, e preenche o pré-menu com caracteres (dígitos).

Após a operação, pode ser:
Mais comumente:
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

ou seja, o resultado muitas vezes difere do valor real por uma pequena quantidade.

Grandes erros ocorrem muito raramente:
с = 2.3

Aqui, há duas explicações:
1) parte da cadeia de bits foi afetada na memória ao chamar a ou b, ou seja, as variáveis a e b foram alteradas.
2) um erro ocorreu durante a operação de "dividir".

Eu acho que 2) ocorre com mais freqüência. Por que eu não sei. Acho que tem a ver com o fato de que o co-processador tem a intenção de ser altamente otimizado em detrimento da inutilidade.

Ao comparar uma variável com a número 2.000....00, a igualdade obviamente falhará. Nem todos os bits serão iguais.

Agora, a NormalizeDouble() está aqui para ajudar!
NormalizeDouble() irá "corrigir" este pequeno erro!
Como o erro é freqüentemente muito pequeno, arredondamentos com uma pequena precisão sempre darão o resultado correto.

Veja as coisas desta maneira:
Arredondar o número a = 2.111...11 para o segundo dígito.
NormalizeDouble() irá escrever 2,11 em uma nova variável e preencher os pedaços restantes com zeros, não uns!
Acho que será parecido com isto:

double MyNormalizeDouble(double value, int digits)
{
     int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                       с помощью которого мы из VALUE сделаем целое число
     double result = MathRound(factor * value) / factor;
     return(result);
}
Aqui, eu tentei o melhor para explicar porque NormalizeDouble() é necessário.

Até recentemente eu estava completamente satisfeito com esta explicação, mas recentemente me convenci de que este esquema nem sempre funciona.

NormalizeDuplo(a, 2) ! NormalizeDuplo(b, 2) onde !OC! - é um operador de comparação.
Embora, de acordo com meu entendimento, isso sempre deve funcionar!
Portanto, ficarei feliz em receber qualquer crítica fundamentada e compreensível!
 
gravity001:
SK. escreveu (a):
...

Na situação atual, o valor inicial da variável 123.00000000000 pode ser 122.999999999999999999 no momento em que ela for utilizada nos cálculos. E isto apesar do fato de que, desde que a variável foi descoberta, seu valor nunca mudou, mas somente foi solicitado pelo programa para participar de outros cálculos.

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

Você tem certeza do que está dizendo? Se você pudesse indicar a fonte de seus conhecimentos?
Tenho certeza. A fonte de seu conhecimento é sua própria experiência em programação MQL4 e consultas aos desenvolvedores.
1? se o problema está em lembrar ou ler uma variável, como NormalizeDouble() pode ajudar, se o valor de retorno também é lembrado ou lido com um erro?
NormalizeDouble() deve ser aplicado imediatamente antes da operação de comparação. O resultado da operação de comparação é um valor do tipo booleano, que nunca é "corrompido".
2? por que o esquema NormalizeDuplo(valor, dígitos) ! NormalizeDouble(valor, dígitos) , onde !OC! é o operador de comparação, nem sempre funciona... Mesmo que você insira diretamente no if?
Eu não disse isso. É exatamente assim que funciona e é isso que você deve fazer.
3? Você sabe como funciona o NormalizeDouble() (algoritmo de função)?
Não, eu não tenho. Por favor, consulte os desenvolvedores.
4? eu escrevi minha opinião sobre este assunto, o que você acha?
Sua opinião é interessante, mas esta questão já foi resolvida há muito tempo. É melhor usar as recomendações dos desenvolvedores e não reinventar a roda.
 
SK. писал (а):
gravidade001:

2? por que o esquema NormalizeDuplo(valor, dígitos) !OC! NormalizeDouble(valor, dígitos) , onde !OC! é um operador de comparação, nem sempre funciona, mesmo que você o insira diretamente no if?
Eu não disse isso. É exatamente assim que funciona e é assim que você deve fazer.

Aqui estão mais opiniões sobre este assunto

Novamente sobre a comparação de duas duplas, 1 página a partir do primeiro post!

Inteiro 24.12.2006 15:23

Infelizmente, a construção NormalizeDouble(x-y,Digits) não é idêntica à construção NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits)

Renat 24.12.2006 16:15

E não deve ser idêntico. A primeira é correta.

Eu acho que a construção é
if (NormalizeDuplo(x,Dígitos) - NormalizeDuplo(y,Dígitos) != 0)
e a construção
se (NormalizeDuplo(x,Dígitos) != NormalizeDuplo(y,Dígitos))
são idênticos!

O que você acha?
 
gravity001:

Renat 24.12.2006 16:15

E não deve ser idêntico. A primeira é correta.

Eu acho que a construção
if(NormalizeDuplo(x,Dígitos) - NormalizeDuplo(y,Dígitos) != 0)
e a construção
se (NormalizeDuplo(x,Dígitos) != NormalizeDuplo(y,Dígitos))
são idênticos!

O que você acha?


E a opinião de Renat não é interessante? Você não está interessado na opinião do CEO da empresa que desenvolve a MT?

Ou você é como a velha mulher do conto de fadas de Pushkin? Basta querer-querer-querer-querer! Lembre-se como termina a história. "Os peixes não disseram nada. Ela abanou a cauda e nadou até o mar azul. Ele esperou muito tempo junto ao mar por uma resposta. Ele não esperou, voltou para a velha mulher"...

 
SK. писал (а):
A primeira é a gravidade001:


Renat 24.12.2006 16:15

E não deve ser idêntico. A primeira é correta.

Eu acho que a construção
if(NormalizeDuplo(x,Dígitos) - NormalizeDuplo(y,Dígitos) != 0)
e a construção
se (NormalizeDuplo(x,Dígitos) != NormalizeDuplo(y,Dígitos))
são idênticos!

O que você acha?



E a opinião de Renat não é interessante? Você não está interessado na opinião do CEO da empresa que desenvolve a MT?


Ou você é como a velha mulher do conto de fadas de Pushkin? Basta querer-querer-querer-querer! Lembre-se como termina a história. "Os peixes não disseram nada. Ela abanou a cauda e nadou até o mar azul. Ele esperou muito tempo junto ao mar para obter uma resposta. Ele não esperou, voltou para a velha mulher"...



Bem, Renat disse que o primeiro caminho é certo e o segundo é errado, e você disse que o segundo caminho é certo, certo?

2? por que o esquema NormalizeDuplo(valor, dígitos) !OC! NormalizeDouble(valor, dígitos) , onde !OC! é um operador de comparação, nem sempre funciona, mesmo que você o insira diretamente no if?
Eu não disse isso. É exatamente assim que funciona, e é assim que deve ser feito.
 

Eu disse isso no sentido de uma comparação mais ou menos:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))

o que significa que as construções do tipo nem sempre funcionam:

double a = NormalizeDouble(x,Digits);
double b = NormalizeDouble(y,Digits);
 
if (a > b)
  {
  ...
  }

ou seja, NormalizeDouble() deve ser inserido diretamente no cabeçalho do operador, o mais próximo possível do local onde a operação de comparação é calculada.

Quanto à opinião dos desenvolvedores, não pretendo desafiá-la.

E então... esse fio tratou de uma construção totalmente diferente:

 
SK. писал (а):

Eu disse isso implicando uma comparação mais ou menos:

if (NormalizeDouble(x,Digits) > NormalizeDouble(y,Digits))
Eu não verifiquei mais ou menos, mas eu verifiquei a igualdade.
Eu tinha erros de comparação quando usei esta construção:

if (NormalizeDouble(x, digits) == NormalizeDouble(y, digits))
{
    ...
}
Por que, você não sabe?