Вопрос к мастерам MQL4. Опять про Double Compare. - страница 9

 
SK. писал (а):

Я так сказал подразумевая сравнение на больше-меньше:

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

имея ввиду, что не всегда работают конструкции вида:

double a = NormalizeDouble(x,Digits);
double b = NormalizeDouble(y,Digits);
 
if (a > b)
  {
  ...
  }
А по моему первое и второе с точки зрения результата ОДНО И ТО ЖЕ.
Результаты присваиваемые переменным a и b нормализованы и дальше их уже можно сравнивать, ничего с ними не станет.
Ренат же писал про другое, ибо в том примере результат вычитания нормализованных значений в свою очередь не нормализовывался.
Если нормализовывать итоговый результат операции, то его можно присваивать переменной и дальше ей оперировать. Главное чтобы сама переменная в дальнейшем не изменяла своего значения.
 
gravity001:
На больше или меньше я не проверял эту конструкцию, а вот на равенство проверял.
У меня были ошибки при сравнении, когда я использовал такую конструкцию:

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

Какие ошибки?
 
Simca:
А по моему первое и второе с точки зрения результата ОДНО И ТО ЖЕ.

В ряде случаев это действительно работает, но не всегда. Это "не всегда" диктуется своеобразными способами хранения значений в памяти компьютера. В том-то и дело.

Результаты присваиваемые переменным a и b нормализованы и дальше их уже можно сравнивать, ничего с ними не станет.
Нельзя. Т.е. делать можно что угодно, но для получения гарантированного результата следует применять NormalizeDouble() прямо в выражении, содержащем операцию сравнения.

Ренат же писал про другое, ибо в том примере результат вычитания нормализованных значений в свою очередь не нормализовывался.
Да. Но это не значит, что предыдущие Ваши утверждения верны.

Если нормализовывать итоговый результат операции, то его можно присваивать переменной и дальше ей оперировать. Главное чтобы сама переменная в дальнейшем не изменяла своего значения.
Она может изменить значение в последнем знаке по причине используемой специфической компьютерной технологии. Это может произойти и происходит незаметно для пользователя. В том-то и дело. В ряде случаев сработает (например, в период отладки программы), а при использовании этой программы зачастую сработает как ожидалось незадачливым программистом, а иногда возьмёт и не сработает.

 

Приношу свои искренние соболезнования разработчикам, вынужденным по 1000 раз объяснять одно и то же каждому новому юзеру..

 
SK. писал (а):
gravity001:
На больше или меньше я не проверял эту конструкцию, а вот на равенство проверял.
У меня были ошибки при сравнении, когда я использовал такую конструкцию:

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

Какие ошибки?
Не выполняется условие, т.е. не выполняется равенство?
И еще, почему Вы думаете ошибка в хранении или чтении переменных double из памяти? Может ошибка в арифметических операциях?

Думаете, не может быть ошибки в таком случае:

double a = 4.0;
double b = 2.0;

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

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

Продемонстрируйте пожалуйста эту ошибку!!!!
 
gravity001:
Не выполняется условие, т.е. не выполняется равенство?
И еще, почему Вы думаете ошибка в хранении или чтении переменных double из памяти? Может ошибка в арифметических операциях?

Думаете, не может быть ошибки в таком случае:

double a = 4.0;
double b = 2.0;

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

Думаю, что сама операция деления исполняется правильно.

Обсуждаемый вопрос касается не способа получения значения некоторой переменной (будь то значение, полученное в результате вычислений или при инициализации переменной), а касается судьбы значения этой переменной в процессе исполнения программы и даже просто работы компьютера. А судьба её непредсказуема. Поэтому при программировании логических операций следует применять краснознамённую функцию NormalizeDouble().

Применять - хорошо. Правильно применять - очень хорошо.

Не применять - плохо. Неправильно применять - плохо.

---

В отпуск хочу..

 
SK. писал (а):
В ряде случаев это действительно работает, но не всегда. Это "не всегда" диктуется своеобразными способами хранения значений в памяти компьютера. В том-то и дело.
О способах хранения значений в памяти компьютера я знаю. :) Стаж программирования около 20 лет. Даже студентов в университете в прошлом программированию учил.

Результаты присваиваемые переменным a и b нормализованы и дальше их уже можно сравнивать, ничего с ними не станет.
Нельзя. Т.е. делать можно что угодно, но для получения гарантированного результата следует применять NormalizeDouble() прямо в выражении, содержащем операцию сравнения.

Естественно перед тем как сравнить результат вычисления какого-либо выражения с чем-либо, надо этот результат нормализовать! Кто ж с этим спорит?! Но это к нашему спору отношения не имеет. Я говорил об идентичности кода. А вся разница в нем, в том что во втором случае результаты нормализации сохраняются в переменных. И ВСЕ!

Т.е. Вы утверждаете, что функция NormalizeDouble имеет результат с разрядностью выше double (результат функции занимает больше бит памяти, хотя бы на один бит). Ибо только этим я могу объяснить какую-либо потерю (или изменение) при сохранении результата функции в переменной. Или при присвоении какая-то хитрая операция производится, а не просто побайтное дублирование данных из одних ячеек памяти в другие???

Еще раз говорю, я не обсуждаю корректность раздельных нормализаций правого и левого операнда оперции сравнения или еще что-то. Вопрос стоит только об идентичности результатов двух выше приведенных фрагментов кода.

Если нормализовывать итоговый результат операции, то его можно присваивать переменной и дальше ей оперировать. Главное чтобы сама переменная в дальнейшем не изменяла своего значения.
Она может изменить значение в последнем знаке по причине используемой специфической компьютерной технологии. Это может произойти и происходит незаметно для пользователя. В том-то и дело. В ряде случаев сработает (например, в период отладки программы), а при использовании этой программы зачастую сработает как ожидалось незадачливым программистом, а иногда возьмёт и не сработает.

УАУ! И какие такие "специфические компьютерные технологии" Вы имеете в виду? Для пользователя вообще много чего "происходит незаметно", но мы то с Вами программисты как-никак. :) Для нас ничего не должно происходить незаметно, иначе это уже не компьютер будет а генератор непредсказуемого результата. :) Или у нас в компьютере уже странствующие биты появились? То так прочитаются, а то эдак... Еще раз! При арифметических операциях с вещественными числами результат действительно не является абсолютно точным (связано со способом представления вещественных чисел). Но это не касается операций присвоения. После того как функция NormalizeDouble отработала и вернула результат типа double, этот результат помещается в переменную простым копированием значения (все байты совпадут). В дальнейшем, пока значение переменной не изменяется (т.е. оно только читается, но в него ничего не записывается), оно сохраняется в первоначальном виде и никакие знаки ни в каком разряде у него не плавают. Хоть зачитайся - получишь одно и то же. А вот достаточно его хотя бы умножить на 1 и записать результат обратно - тут уж ничего не гарантируется.

 
SK. писал (а):

Приношу свои искренние соболезнования разработчикам, вынужденным по 1000 раз объяснять одно и то же каждому новому юзеру..

Это уже откровенный наезд - пожалуй проигнорирую. :)
 
gravity001:

Думаете, не может быть ошибки в таком случае:

double a = 4.0;
double b = 2.0;

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

В данном случае результат операции будет ПРИБЛИЗИТЕЛЬНО 2.0
Ошибка в очень далеких разрядах вполне может получиться из-за способа представления вещественных чисел.
Причина обращения: