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

 
SK. писал (а):
VBAG:
Уж от Вас то, я такого никак не ождал.

Беру свои слова обратно.
Рад, что ошибся в своих сомнениях.
 

К SK

Вам виднее. Я не считаю MQL языком программирования. Просто такой ДИАЛЕКТ.

Кстати, задолбали ДВЕ вещи в нем:

1) нету перечисления операций, то есть обязательно фигурные скобки

2) return - ужасно достает необходимостью круглых скобок

А в общем и целом - ребята МОЛОДЦЫ.

Керниган с Ритчи - поаплодировали б им.

 
VBAG писал (а):
Беру свои слова обратно.
Рад, что ошибся в своих сомнениях.


А мы и не ссорились:)

Depfy:

Я не считаю MQL языком программирования. Просто такой ДИАЛЕКТ.

Наверное, это вопрос терминологии. Я, например, нахожу в MQL все признаки полноценного языка. Так или иначе, но это один из немногих языков (заметьте, лучший), предоставляющих трейдеру возможность механизировать и автоматизировать свою деятельность. Мне этот язык представляется вполне удовлетворительным хотя бы в том смысле, что его возможности многократно перекрывают потребности большинства алгоритмов (иными словами - хватало бы состоятельных замыслов, а средства для реализации уже имеются).
 
SK. писал (а):
...

А при существующем положении дел исходное значение переменной 123.00000000000 к моменту её использования в вычислениях может оказаться 122.999999999999. И это при том, что с момента открытия переменной её значение ни разу не изменялось, а только запрашивалось программой для участия в других вычислениях.


Собственно, потому и весь сыр-бор. Потому и возникла необходимость использования NormalizeDouble() как можно ближе к собственно вычислению, желательно прямо в Условии оператора if, for, while.

Вы уверенны в своих словах? Если можно укажите источник ваших знаний?

Тогда у меня к вам такой вопрос

1? если проблема в запоминании или прочтении переменной, то как может помочь NormalizeDouble(), если возращаемое значение так же запомниться или прочитается с ошибкой?
2? почему схема NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , где !ОС! - оператор сравнения, не всегда работает? даже если её прямо в if вставить?
3? Вы знаете как работает NormalizeDouble() (алгоритм функции)?
4? я писал свое мнение по этому поводу, что Вы дамаете?

gravity001 писал (а):

...
Про нормализацию я уже говорил. Сначала расскажите, зачем ее применять, а уже потом как и где.

Вот ключевой вопрос, да? Сам думал над этим долго: "вводишь double и получаешь double"  . Что может вроде измениться?
Точного ответа не нашел. Но представляю себе это так

double a = 2.000000000000
double b = 2.000000000001
double c = 1.999999999999

Все эти переменные разные и в памяти они храняться с точностья до последнего знака (цифры)!
В этом случае мы сами определяем знаки (цифры). Все что не определили заполняется нулями.

Если бы мы задовали double a = 2.0, а в памяти это запоминалось уже как 2.0000001 или как 1.9999999, то ясно, что NormalizeDouble() тогда бы не помогла, так как возращала бы уже неточное значение!
Я думаю, что такая ошибка при запоминании значения переменной бывает почти никогда. Тем более я не думаю что число 2.0 специально запоминается как 1.9999999999999, так как за каждый знак (цифру или точку) отвечат определенный бит в битовой строке памяти! Поэтому число 2.0 надежно храниться как 2.00000...00.

Другой случай, когда знаки мы не сами определяем:

a = 4.0;
b = 2.0; 
c = a / b // - операцию "деления" делает процессор, а вернее сопроцессор, и он же заполняет пременную знаками (цифрами).

После операции может быть:
Чаще всего:
с = 2.000...0
с= 1.99999999...
с= 2.00000001...

т.е. результат частенько отличеется от истинного на маленькую величину.

Большие ошибки всчтречаются очень редко:
с = 2.3

Здесь, есть два объяснения:
1) часть битовой строки пострадало в памяти при вызове a или b, т.е. изменились переменные а и b.
2) произошла ошибка при операции "деления".

Я думаю, что чаще всего происходит 2). Почему я не знаю. Думаю, это связано с тем, что работу сопроцессора стараються сильно оптимизировать в ущерб надожности.

Ясно, что при сравнении переменной с с числом 2.000...00 равенство не выполниться. Так как не все биты будут совпадать.

Вот теперь, NormalizeDouble()  призвано помочь!
NormalizeDouble() "исправит" эту маленькую погрешность!
Так как погрешность, чаще всего, очень маленькая, то округление с небольшой точностью будут всегда давать правильный результат.

Выглядеть это будет так:
Округлим число  a = 2.111...11 до второго знака.
для этого NormalizeDouble() запишет в новую переменную сначало 2. 11,  а оставшиеся биты заполнит нулями, а не однерками!
Думаю вуглядеть это будет так:

double MyNormalizeDouble(double value, int digits)
{
     int factor = MathRound( MathPow(10, digits) ); // factor - это множитель,
                                                       с помощью которого мы из VALUE сделаем целое число
     double result = MathRound(factor * value) / factor;
     return(result);
}
Вот, постарался объяснить как мог, зачем нужна NormalizeDouble().

До недавнего времени это объяснение меня полностью устраивало. Но недавно сам убедился, что такая схема не всегда работает

NormalizeDouble(a, 2) !OC! NormalizeDouble(b, 2), где !OC! - это оператор сравнения.
Хотя по моим представлениям она должно работать всегда!
Поэтому буду рад Любой аргументированной и понятной критике!
 
gravity001:
SK. писал (а):
...

А при существующем положении дел исходное значение переменной 123.00000000000 к моменту её использования в вычислениях может оказаться 122.999999999999. И это при том, что с момента открытия переменной её значение ни разу не изменялось, а только запрашивалось программой для участия в других вычислениях.

Собственно, потому и весь сыр-бор. Потому и возникла необходимость использования NormalizeDouble() как можно ближе к собственно вычислению, желательно прямо в Условии оператора if, for, while.

Вы уверенны в своих словах? Если можно укажите источник ваших знаний?
Уверен. Источником знаний является собственный опыт программирования на MQL4 и консультации разработчиков.
1? если проблема в запоминании или прочтении переменной, то как может помочь NormalizeDouble(), если возращаемое значение так же запомниться или прочитается с ошибкой?
NormalizeDouble() следует применять непосредственно перед операцией сравнения. Результатом операции сравнения является значение логического типа, которое не "портится" никогда.
2? почему схема NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , где !ОС! - оператор сравнения, не всегда работает? даже если её прямо в if вставить?
Я такого не говорил. Как раз именно так и работает,так и надо делать.
3? Вы знаете как работает NormalizeDouble() (алгоритм функции)?
Нет, не знаю. С этим к разработчикам.
4? я писал свое мнение по этому поводу, что Вы дамаете?
Ваше мнение интересно, но этот вопрос уже давно решён. Лучше воспользоваться рекомендацией разработчиков и не изобратать велосипед.
 
SK. писал (а):
gravity001:

2? почему схема NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , где !ОС! - оператор сравнения, не всегда работает? даже если её прямо в if вставить?
Я такого не говорил. Как раз именно так и работает,так и надо делать.

Вот, еще мнения по этому вопросу

'И снова о сравнении двух double', 1 страница с самого первого поста!

Integer 24.12.2006 15:23

к сожалению конструкция NormalizeDouble(x-y,Digits) не идентична конструкции NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits)

Renat 24.12.2006 16:15

А она не должна быть идентичной. Правильная первая.

я думая конструкция
if (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
и конструкция
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
одинаковые!

Что скажите?
 
gravity001:

Renat 24.12.2006 16:15

А она не должна быть идентичной. Правильная первая.

я думая конструкция
if (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
и конструкция
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
одинаковые!

Что скажите?


А мнение Рената что..? не интересно??? Мнение генерального директора компании-разработчика МТ Вам не интересно?

Или Вы как та старуха из сказки А.С. Пушкина? Только хочу-хочу-хочу! Вспомните чем сказка кончилась. "Ничего не сказала рыбка. Хвостом вильнула и уплыла в синее море. Долго у моря ждал он ответа. Не дождался, к старухе воротился.."

 
SK. писал (а):
gravity001:


Renat 24.12.2006 16:15

А она не должна быть идентичной. Правильная первая.

я думая конструкция
if (NormalizeDouble(x,Digits) - NormalizeDouble(y,Digits) != 0)
и конструкция
if (NormalizeDouble(x,Digits) != NormalizeDouble(y,Digits))
одинаковые!

Что скажите?



А мнение Рената что..? не интересно??? Мнение генерального директора компании-разработчика МТ Вам не интересно?


Или Вы как та старуха из сказки А.С. Пушкина? Только хочу-хочу-хочу! Вспомните чем сказка кончилась. "Ничего не сказала рыбка. Хвостом вильнула и уплыла в синее море. Дулго у моря ждал он ответа. Не дождался, к старухе воротился.."



Вот, Ренат и сказал, что правильный первый вариант и неправильный второй, а вы сказали что и второй вариант правильный, так?

2? почему схема NormalizeDouble(value, digits) !OC! NormalizeDouble(value, digits) , где !ОС! - оператор сравнения, не всегда работает? даже если её прямо в if вставить?
Я такого не говорил. Как раз именно так и работает,так и надо делать.
 

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

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

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

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

т.е. NormalizeDouble() следует вставлять прямо в загловок оператора, как можно ближе к месту вычисления операции сравнения.

Что касается мнения разработчиков, то я не предполагаю это мнение оспаривать.

И потом.. в той ветке шла речь о совсем иной конструкции:

 
SK. писал (а):

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

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

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