Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Похоже, этот разговор будет продолжаться бесконечно. До тех пор, пока новый юзер обретёт должный опыт и знания, он, как правило, успевает наколоться на нормализации несколько раз.
Пожалуй, в МТ5 имеет смысл принудительно ограничивать точность действительных чисел при исполнении операций сравнения, скажем, до 8 знака после запятой (т.е. принудительно исполнять NormalizeDouble() с digit=8).
Если операция сравнения будет использоваться многократно (в рекурентных расчетах, и т.д.), то при округлении до 8 знаков на входе, погрешность на выходе может быть соизмерима с 1.
У меня был такой опыт с вычислением SmoothedAvarege, вычисляя его в своем приложении год назад. После этого я стараюсь избирать такие методы работы которые не трогают разрядность даблов.
Либо как предложил gravity001 перходить к INTам(что, сами понимаете, очень трудоемко).
Пожалуй, в МТ5 имеет смысл принудительно ограничивать точность действительных чисел при исполнении операций сравнения, скажем, до 8 знака после запятой (т.е. принудительно исполнять NormalizeDouble() с digit=8).
Однако терминал замедляют не только операции, заданные пользователем, но и операции, скрытые от него. Мне кажется предпочтительнее просто ввести в язык фунцию ComparePrice. Кстати, также как и Irtron считаю естественной мерой Point/2 (возможно лучше Point *0.5). Чтобы не делить/умножать каждый раз, эту половинку можно сделать предопределённой переменной. А пока этого нет, можно ввести такую переменную самому и вычислять её один раз при первом запуске start. Хотя в силах разработчиков и сделать функцию сравнения double с заданной точностью, то есть то же, но с digits вместо Point/2.
Ну нагородили... :)
Сравнение плавающих чисел - делается сравнением модуля разности с маленьким порогом.
return (fabs(d1-d2) < 1e-10) к примеру.
Зачем мутить воду... Функция NormalizeDouble(...) - для красивых отчетов нужна, и не более.
Но Вы не догнали суть вопроса, читать надо внимательнее. Суть вопроса - стиль программирования вообще, и в конкретном случае MT4.
Ну нагородили... :)
Сравнение плавающих чисел - делается сравнением модуля разности с маленьким порогом.
return (fabs(d1-d2) < 1e-10) к примеру.
Зачем мутить воду... Функция NormalizeDouble(...) - для красивых отчетов нужна, и не более.
Но Вы не догнали суть вопроса, читать надо внимательнее. Суть вопроса - стиль программирования вообще, и в конкретном случае MT4.
А сказали бы в чем суть вопроса... А то намеки - я не!понимаю :)
Если речь о быстродействии, то в совр. процессорах плавающие операции выполняются
почти так же быстро, как и целочисленные. Что касается СТИЛЯ, то, сори, прагматизм рулит...
Когда АШИПКИ кругом, то о каком стиле речь... Лишь бы работало. ..
А то нету других проблем, чем сравнить два числа :))))))))
Уж от Вас то, я такого никак не ождал. Ни в коем случае нельзя!
Если операция сравнения будет использоваться многократно (в рекурентных расчетах, и т.д.), то при округлении до 8 знаков на входе, погрешность на выходе может быть соизмерима с 1.
У меня был такой опыт с вычислением SmoothedAvarege, вычисляя его в своем приложении год назад. После этого я стараюсь избирать такие методы работы которые не трогают разрядность даблов.
Либо как предложил gravity001 перходить к INTам(что, сами понимаете, очень трудоемко).
Минуточку. Не нужно скоропостижных выводов.
Во-первых. Я не предлагаю принудительно округлять собственно значения самой действительной переменной. Я предлагаю сделать принудительное округление сравниваемых значений (копий) переменных при вычислении результата опериции сравнения (для умолчательного случая). А собственно значение переменной, разумеется, трогать нельзя. При этом никакие другие вычисляемые значения не пострадают, т.к. исходные значения переменных, используемых в операции сравнения, сохраняют свои значения, и ошибки в циклических расчётах накапливаться не будут.
Во-вторых. Я сказал, что для того, чтобы исключить ошибки с более тяжёлыми последствиями, можно пойти по такому пути. Однако, для того, чтобы обеспечить и более требовательные вычисления, необходимо сохранить возможность штатного использования функции NormalizeDouble() с заданными параметрами.
Таким образом, моё предложение не ограничивает возможности языка, а расширяет их.
Иное дело, что незадачливый юзер, не знающий о подобных преобразованиях, и в этом случае тоже может получить непонятный ему результат. Однако, учитывая, что в операциях сравнения, как правило, используются значения цены (т.е, digit = 4), в подавляющем большинстве случаев эта ошибка просто не возникнет. Таким образом, использование предлагаемой технологии повлечёт снижение количества ошибок, приводящих к непредсказуемым последствиям.
А пока этого нет, можно ввести такую переменную самому и вычислять её один раз при первом запуске start.
Нельзя.
Вернее, написать программные строки можно, однако никто ( в т. ч. и разработчики) не даст гарантии, что значение этой переменной будет строго неизменным в течение всего срока работы советника. Дело здесь не в точности программного кода, а в технологических особенностях вычислений и в технологических правилах хранения значений переменных. Если бы не это, то и вопрос не возник бы.
А при существующем положении дел исходное значение переменной 123.00000000000 к моменту её использования в вычислениях может оказаться 122.999999999999. И это при том, что с момента открытия переменной её значение ни разу не изменялось, а только запрашивалось программой для участия в других вычислениях.
Собственно, потому и весь сыр-бор. Потому и возникла необходимость использования NormalizeDouble() как можно ближе к собственно вычислению, желательно прямо в Условии оператора if, for, while.
А пока этого нет, можно ввести такую переменную самому и вычислять её один раз при первом запуске start.
Нельзя.
Вернее, написать программные строки можно, однако никто ( в т. ч. и разработчики) не даст гарантии, что значение этой переменной будет строго неизменным в течение всего срока работы советника. Дело здесь не в точности программного кода, а в технологических особенностях вычислений и в технологических правилах хранения значений переменных. Если бы не это, то и вопрос не возник бы.
А при существующем положении дел исходное значение переменной 123.00000000000 к моменту её использования в вычислениях может оказаться 122.999999999999. И это при том, что с момента открытия переменной её значение ни разу не изменялось, а только запрашивалось программой для участия в других вычислениях.
Собственно, потому и весь сыр-бор. Потому и возникла необходимость использования NormalizeDouble() как можно ближе к собственно вычислению, желательно прямо в Условии оператора if, for, while.
Елы-палы, какжется начинаю понимать, к чему весь базар...
В общем и целом, полагаю, НИЧЧЕЕГГО не надо придумывать. Ибо все зависит от КОНКРЕТНОЙ ситуевины. Какая цель? Если два числа отличаться могут мантиссой в 0.1, и если это КРИТИЧНО, - один коленкор. если не важно - другой. Смотря что сравнивать друг с другом. Но ГИБКОСТЬ, которую дает ОБЫЧНЫЙ компилятор без выкрутасов, - ДОСТАТОЧНАЯ и необходимая вещь, ИМХО.
:)
Елы-палы, какжется начинаю понимать, к чему весь базар...
В общем и целом, полагаю, НИЧЧЕЕГГО не надо придумывать. Ибо все зависит от КОНКРЕТНОЙ ситуевины. Какая цель? Если два числа отличаться могут мантиссой в 0.1, и если это КРИТИЧНО, - один коленкор. если не важно - другой. Смотря что сравнивать друг с другом. Но ГИБКОСТЬ, которую дает ОБЫЧНЫЙ компилятор без выкрутасов, - ДОСТАТОЧНАЯ и необходимая вещь, ИМХО.
:)
Насчёт "придумывать" не могу ответить. Видимо, это зависит от того, о чём думать:)
Например, придумывания типа Point/2 действительно в ряде случаев позволяют вести вычисления с некоторой заданной точностью. Однако, лучше воспользоваться рекомендацией разработчиков, а именно раз и навсегда (вплоть до новой документации) взять за правило использовать при вычислении операций сравнения штатную функцию NormalizeDouble().
Оно и не играет, если использовать NormalizeDouble(). А если не использовать, то как повезёт.