Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
...
Вся прелесть, кода который предложил Irtron, заключается в его компактности( абсолютно ничего лишнего-даже на переменных экономия!)
...
Вот, посмотрел метод, который предложил Irtron
Он и Компактный и быстрее моего, но даже на первый взглят выглядит подозрительным, потому что в сравнении участвуют две переменные double!!!!
В этой схеме только digit выступает как константа и может сравниваться, а переменная а, которая тоже сравнивается, как была ненормализованная double так ею и осталась!
Это вызывает подозрение? (Под коонстантой я понимаю обычные константы - "#define" и те переменный которые не участвовали в операциях).
Так же в других ветка сами разработчики писали, что даже константы double лучше не сравнивать!!!
И так тоже не правильно делать NormalizeDouble(а) !OC! NormalizeDouble(b), !OC! - оператор сравнения!
Тем более, что в первоначальном варианте вместо константы digits было так b = Point / 2 - здесь уже две из двух ненормализованных переменных?
Хотелось бы верить, что этот вариант гениальный, но прежде развейте мои сомнения!
Может и в моем варианте кто-нибудь ошибки найдет?
Вот, посмотрел метод, который предложил Irtron
Смотрите внимательнее, пожалуйста.
Тем более, что в первоначальном варианте вместо константы digits было так b = Point / 2 - здесь уже две из двух ненормализованных переменных?
Про нормализацию я уже говорил. Сначала расскажите, зачем ее применять, а уже потом как и где.
Например, может Вы знаете, зачем сравнивать цены с точностью именно 14 знаков, которая упомянута как некое достижение в обсуждении выше? :) Напомню, функция, которую я предложил, называется ComparePrice. :)
Irtron писал (а):
...
Я предлагал иной метод.
Смотрите внимательнее, пожалуйста.
...
О каких вариантах речь?
Про нормализацию я уже говорил. Сначала расскажите, зачем ее применять, а уже потом как и где.
Например, может Вы знаете, зачем сравнивать цены с точностью именно 14 знаков, которая упомянута как некое достижение в обсуждении выше? :) Напомню, функция, которую я предложил, называется ComparePrice. :)
...
int ComparePrice(double a, double b)
{
a -= b;
b = Point / 2.;
if (a > b)
return (1);
if (a < -b)
return (-1);
return (0);
}
Напомню, функция, которую я предложил, называется ComparePrice. :)
Если вы заметили, я тоже цитировал функцию, которая называлась ComparePrice. Просто Вашу уже модифицировал VBAG. Поэтому я и писал про перваначальный вариант имея виду оригинал, т.е. Вашу функцию!
Сам Тестировал обе функции. Да оказались они быстрее. Но как проверить надежность сравнения? Меня сильно смущает сравнение двух переменных double? Хотя все должно быть правильно так как береться интервал! Но все равно есть подозрения, что она не всегда будет работать правильно!
Вот ключевой вопрос, да? Сам думал над этим долго: "вводишь 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, а оставшиеся биты заполнит нулями, а не однерками!
Думаю вуглядеть это будет так:
Вот, постарался объяснить как мог, зачем нужна NormalizeDouble().
До недавнего времени это объяснение меня полностью устраивало. Но недавно сам убедился, что такая схема не всегда работает
Поэтому буду рад Любой аргументированной и понятной критике!
Так же в других ветка сами разработчики писали, что даже константы double лучше не сравнивать!!!
Если можно, то приведите ссылочку, пожалуйста!
Возник вопрос к разработчикам:
Поясните, пожалуйста, какие есть ограничения или возможные проблемы при сравнении даблов с использованием констант:
1.
double a=1.23456789;
double b;
if(a>b) или if(a<b)
И в таком виде:
2.
#define a 1.23456789;
double b;
if(a>b) или if(a<b)
Тем более, что в первоначальном варианте вместо константы digits было так b = Point / 2 - здесь уже две из двух ненормализованных переменных?
Но в свете Вашего заявления по поводу ненадежности сравнения дабл констант весь смысл теряется. Надо разобраться получше с этим вопросом.
Интересно, что скажут разработчики.
...
Вот это для меня новость! Что называется - вопрос по-существу!
Если можно, то приведите ссылочку, пожалуйста!
...
Помню, где-то кто-то писал, но не помню где(((((. Поэтому, наверно, не корректно с моей стороны было написать: "в других ветка сами разработчики писали"!
Извеняюсь.
Но если найду обязательно ссылку выложу.
Мне кажется, это я читал в книжке по С++. Там было описано как надо сравнивать вещественные числа и там было написано, что лучше всего переходить к целым!
...
Вот это для меня новость! Что называется - вопрос по-существу!
Если можно, то приведите ссылочку, пожалуйста!
...
Помню, где-то кто-то писал, но не помню где(((((. Поэтому, наверно, не корректно с моей стороны было написать: "в других ветка сами разработчики писали"!
Извеняюсь.
Но если найду обязательно ссылку выложу.
Мне кажется, это я читал в книжке по С++. Там было описано как надо сравнивать вещественные числа и там было написано, что лучше всего переходить к целым!
Возник вопрос к разработчикам:
Поясните, пожалуйста, какие есть ограничения или возможные проблемы при сравнении даблов с использованием констант:
1.
double a=1.23456789;
double b;
if(a>b) или if(a<b)
И в таком виде:
2.
#define a 1.23456789;
double b;
if(a>b) или if(a<b)
Похоже, этот разговор будет продолжаться бесконечно. До тех пор, пока новый юзер обретёт должный опыт и знания, он, как правило, успевает наколоться на нормализации несколько раз.
Пожалуй, в МТ5 имеет смысл принудительно ограничивать точность действительных чисел при исполнении операций сравнения, скажем, до 8 знака после запятой (т.е. принудительно исполнять NormalizeDouble() с digit=8). И только в том случае, если явно указана функция NormalizeDouble(), проводить нормализацию в соответствии с указанными в ней параметрами. В этом случае вопрос будет вознкать значительно реже, а именно только тогда, когда юзеру будет нужна именно заданная точность. По-моему, этот хрен хоть и немного, но всё же слаще редьки.
Здравствуйте!
Как известно, от стиля программирования и аккуратности в коде зависит не только правильность расчетов, но и надежность работы написанного кода.
Пишем не игрушки, а потому надежность работы написанной программы является самым первым требованием. Большинство расчетов производится в даблах и корректное сравнение в коде
программы двух вещественных чисел, требует определенного подхода и аккуратности.
Пытаюсь выработать "правильный" стиль программирования. Отсюда вопрос:
Для выражения
double a;
double b;
if(a==b) или if(a!=b)
{......} {.... ..}
разработчики рекомендуют так
//+------------------------------------------------------------------+
//| Функция сранения двух вещественных чисел. |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
return(Compare);
}
//+------------------------------------------------------------------+
Корректен ли код?
double a;
double b;
if(a>b) if(a<b)
{......} {......}
Скорей всего, что в общем случае нет. Какой способ корректной проверки избрать?
Какой вообще стиль работы с даблами целесообразнее?
Заранее благодарен всем откликнувшимся.
Ну нагородили... :)
Сравнение плавающих чисел - делается сравнением модуля разности с маленьким порогом.
return (fabs(d1-d2) < 1e-10) к примеру.
Зачем мутить воду... Функция NormalizeDouble(...) - для красивых отчетов нужна, и не более.