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

 
SK. писал (а):

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 de vistas nem sempre funcionam:

double a = NormalizeDouble(x,Digits);
double b = NormalizeDouble(y,Digits);
 
if (a > b)
  {
  ...
  }
Penso que o primeiro e o segundo têm o mesmo resultado.
Os resultados atribuídos às variáveis a e b são normalizados e então eles podem ser comparados, nada lhes acontecerá.
Renat escreveu sobre outra coisa, porque nesse exemplo o resultado da subtração de valores normalizados, por sua vez, não é normalizado.
Se você normalizar o resultado final de uma operação, você pode atribuí-la a uma variável e manipulá-la ainda mais. O principal é que a variável em si não deve mudar seu valor mais adiante.
 
gravity001:
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?

Que tipo de erros?
 
Simca:
E para mim o primeiro e o segundo em termos do resultado UM E UM.

Isto funciona em alguns casos, mas nem sempre. Este "nem sempre" é ditado pela forma peculiar com que os valores são armazenados na memória do computador. É isso mesmo.

Os resultados atribuídos às variáveis a e b são normalizados e podem ser comparados ainda mais, nada acontecerá com elas.
Você não pode. Ou seja, você pode fazer o que quiser, mas para obter um resultado garantido, você deve aplicar NormalizeDouble() diretamente em expressão contendo a operação de comparação.

Renat escreveu sobre outra coisa, porque em seu exemplo o resultado da subtração de valores normalizados não é normalizado.
Sim. Mas isso não significa que suas declarações anteriores estejam corretas.

Se você normalizar o resultado final de uma operação, você pode atribuí-la a uma variável e manipulá-la ainda mais. O principal é que a variável em si não deve mudar seu valor mais adiante.
Ela pode mudar seu valor no último dígito por causa da tecnologia informática específica em uso. Isto pode acontecer e acontece sem que o usuário perceba. A questão é essa. Em alguns casos funcionará (por exemplo, durante a depuração de um programa), e ao utilizar este programa, muitas vezes funcionará como esperado pelo infeliz programador, e às vezes não funcionará.

 

Minhas sinceras condolências aos desenvolvedores que têm que explicar a mesma coisa 1000 vezes a cada novo usuário.

 
SK. писал (а):
gravidade001:
Eu não verifiquei mais ou menos esta construção, mas 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?

Que tipo de erros?
A condição não está preenchida, ou seja, a igualdade não está preenchida?
Além disso, por que você acha que o erro está no armazenamento ou na leitura das variáveis em dobro da memória? Talvez um erro em operações aritméticas?

Você acha que não pode haver erro em tal caso?

double a = 4.0;
double b = 2.0;

double c = a / b; // думаете, здесь в опрерации "деления" не может быть ошибки
                     (т.е. появление цифр отличных от нуля после точки)?
 
gravity001 писал (а):
На больше или меньше я не проверял эту конструкцию, а вот на равенство проверял.
У меня были ошибки при сравнении, когда я использовал такую конструкцию:

if (NormalizeDouble(x, digits) == NormalizeDouble(y, digits))
{
    ...
}
Почему, не знаете?

Favor demonstrar este erro!!!!
 
gravity001:
A condição não está preenchida, ou seja, a igualdade não está preenchida?
Além disso, por que você acha que o erro está no armazenamento ou na leitura das variáveis em dobro da memória? Talvez um erro em operações aritméticas?

Você acha que não pode haver um erro em tal caso?

double a = 4.0;
double b = 2.0;

double c = a / b; // думаете, здесь в опрерации "деления" не может быть ошибки
                     (т.е. появление цифр отличных от нуля после точки)?

Acho que a operação de divisão em si é executada corretamente.

A questão em discussão não é sobre como obter o valor de alguma variável (seja o valor obtido pelos cálculos ou pela inicialização da variável), mas sobre o destino do valor dessa variável durante a execução do programa e até mesmo apenas na operação do computador. E seu destino é imprevisível. Portanto, ao programar operações lógicas, você deve usar a funçãoNormalizeDouble() com a parte vermelha.

Aplicá-lo é bom. Aplicá-lo corretamente é muito bom.

Não usá-lo é ruim. Uso incorreto - ruim.

---

Nas férias eu quero...

 
SK. писал (а):
Funciona em alguns casos, mas nem sempre. Este "nem sempre" é ditado pelas formas peculiares de armazenamento de valores na memória do computador. É isso mesmo.
Conheço as formas de armazenar valores na memória do computador. :) Eu tenho cerca de 20 anos de experiência em programação. Eu até ensinei programação a estudantes universitários no passado.

Os resultados atribuídos às variáveis a e b são normalizados e podem ser comparados ainda mais, nada acontecerá com elas.
Você não pode. Portanto, você pode fazer o que quiser, mas para obter um resultado garantido, você deve aplicar NormalizeDouble() diretamente na expressão que contém a operação de comparação.

Naturalmente, antes de poder comparar o resultado do cálculo de uma expressão com qualquer coisa, você tem que normalizá-la! Quem pode argumentar com isso?! Mas isso é irrelevante para nosso argumento. Eu estava falando sobre a identidade do código. A diferença é que, no segundo caso, os resultados da normalização são armazenados em variáveis. E ISTO É!

Ou seja, você afirma que a função NormalizeDouble tem um resultado com um tamanho de bit maior que o dobro (o resultado desta função ocupa pelo menos um bit de memória). Somente por isso posso explicar qualquer perda (ou mudança) ao salvar o resultado da função em uma variável. Ou, ao atribuir, alguma operação complicada é realizada, e não apenas duplicação de dados de uma célula de memória para outra.

Mais uma vez, não estou discutindo a correção de normalizações separadas dos operandos direito e esquerdo da operação de comparação ou qualquer outra coisa. Estou apenas questionando se os resultados dos dois fragmentos de código acima são idênticos.

Se você normalizar o resultado de uma operação, você pode atribuí-la a uma variável e operá-la posteriormente. O principal é que a variável em si não deve mudar seu valor mais adiante.
Ela pode mudar seu valor no último dígito por causa da tecnologia informática específica utilizada. Isto pode acontecer e acontece sem que o usuário perceba. A questão é essa. Em alguns casos funcionará (por exemplo, durante a depuração de um programa), e ao utilizar este programa, muitas vezes funcionará como esperado pelo infeliz programador, e às vezes não funcionará.

COMO! E que tipo de "tecnologia informática específica" você quer dizer? Muitas coisas "passam despercebidas" para o usuário, mas nós somos, afinal,programadores. :) Nada deve passar despercebido para nós, caso contrário não será um computador, mas um gerador de resultados imprevisíveis. :) Ou talvez nosso computador já tenha alguns pedaços errantes? Eles podem ler de uma maneira ou de outra... Mais uma vez! Em operações aritméticas com números reais, o resultadonão é de fatoabsolutamente exato (tem a ver com a forma como os números reais são representados). Mas isto não se aplica às operações de cessão. Uma vez que a função NormalizeDouble tenha funcionado e retornado um resultado do tipo duplo, este resultado é colocado em uma variável simplesmente copiando o valor (todos os bytes serão correspondidos). Além disso, enquanto o valor variável permanece inalterado (ou seja, só é legível, mas nada está escrito nele), ele é preservado em sua forma original e não há sinais flutuando em nenhum lugar. Leia-o e você terá a mesma coisa. Mas se você apenas multiplicar por 1 e escrever o resultado de volta, nada é garantido.

 
SK. писал (а):

Minhas sinceras condolências aos desenvolvedores que têm queexplicar a mesma coisa1000 vezes a cada novo usuário.

Isso é um ataque gritante - acho que vou ignorá-lo. :)
 
gravity001:

Você acha que não pode haver engano em tal caso:

double a = 4.0;
double b = 2.0;

double c = a / b; // думаете, здесь в опрерации "деления" не может быть ошибки
                     (т.е. появление цифр отличных от нуля после точки)?

Neste caso, o resultado da operação seria APLICÁVEL 2.0
Um erro em dígitos muito distantes pode muito bem ser devido à forma como os números reais são representados.