NormalizeDouble VS MathRound - страница 3

 

Тестер гоняю только на котирвках MQ.

Кстати, ошибка возникала всегда в одном и том же месте. К сожалению хистори не просматривал.

 
kermit писал (а):
Цена должна нормализовываться на уровне терминала или сервера, а не трудами юзера. Я считаю, что это баг, который MQ должны исправить, а не писать, что кто не использует НормалайзДабл - тот лопух.

Я считаю, что программист в своей работе должен иметь следующий настрой:
1. Ого, оказывается есть такая возможность! Отлично, я буду её использовать, но сначала проверю, как она работает.
2. Такой возможности нет. Ерунда, сам сделаю!

 


а не помогать юзерам плодить скрытые ошибки?

или эта ошибка была проплачена? о_О
   Ошибки юзеров дают деньги ДС.
 
Не забывайте, что это язык программирования. Со всеми вытекающими последствиями.
Вмешиваться в логику расчетов эксперта и принудительно автоматически нормализовать результаты всевозможных операций категорически нельзя.
 
Renat:
Не забывайте, что это язык программирования. Со всеми вытекающими последствиями.
Вмешиваться в логику расчетов эксперта и принудительно автоматически нормализовать результаты всевозможных операций категорически нельзя.
Так речь не о нормализациии результатов действия юзера, а о автоматической нормализации входных данных в терминал, а именно цены. Т.е. например оператор Open[] или OrderOpenPrice() должен возвращать уже нормализованную цену. Разве это не баг, если ООР с ордера по евре возвращает цену 1.234599999? А при расчёте прибыли/убытка по этому ордеру будет чудесным образом взята цена открытия 1.2346. Как это возможно?
 
kermit:
Renat:
Не забывайте, что это язык программирования. Со всеми вытекающими последствиями.
Вмешиваться в логику расчетов эксперта и принудительно автоматически нормализовать результаты всевозможных операций категорически нельзя.
Так речь не о нормализациии результатов действия юзера, а о автоматической нормализации входных данных в терминал, а именно цены. Т.е. например оператор Open[] или OrderOpenPrice() должен возвращать уже нормализованную цену. Разве это не баг, если ООР с ордера по евре возвращает цену 1.234599999? А при расчёте прибыли/убытка по этому ордеру будет чудесным образом взята цена открытия 1.2346. Как это возможно?
Если Вы используете штатные котировки от торгового сервера, а не самостоятельно импортированные котировки, то Вы всегда будете получать нормализованные цены (с допустимой точностью) в барах.

Но! Так как вещественные числа в double хранятся с определенной точностью, то вместо 1.2346 можно вполне получить 1.234599999, что является абсолютно корректным значением. Все непонимание начинающих кроется в неприятии погрешностей в представлении вещественных чисел. И аналогичные темы поднимаются каждый месяц. Например, 10 дней назад, я уже отвечал точно по такому же вопросу:

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

Mak 08.06.05 15:41

Еще как могут - и Вы это как раз показали своим примером. Вопрос "как это может появиться?" является теорией, а результат "математические(именно математические, а не только деление/умножение) операции с вещественными числами дают погрешности" - является суровой правдой жизни.
Погрешность для +/- с плавающей арифметикой будет +/- 1-2 эпсилон (или +/- 1-2 эпсилон * Макс(А,В)). Причем чем больше вычислений, тем больше накапливается ошибка.

Эпсилон - это примерно значение младшего разряда мантисы числа.
В языках даже такая константа бывает (в Си кажется есть).
Для double она примерно равна 10 в минус 14 степени.

Причин как минимум 2.

1. Вещественные числа в компе всегда представляются в виде дробного числа.
Т.е. в виде М * 2^Р, где М - мантиса, |M| < 1.0, а Р - порядок, целое со знаком.
Таким способом нельзя точно представить число, все что не влазит в мантису отбрасывается.

2. Числа представляются в двоичной системе, и если мы напишем 1.1 и в десятичной это выглядит просто, то в двоичной будет выглядеть намного сложнее - может получиться периодическая дробь например, которая будет округлена размером мантисы.

В результате может оказаться что 1.1 + 2.2 не равно 3.3
Мы записали в десятичной системе, а в компе они представляются в двоичной системе и в нейже выполняются операции.

Это общая проблема всех компов и всех языков.

Проверять вещественные числа на равенство всегда некорректно (за очень редким исключением).

Равенство можно проверить только с некоторой точностью.
И сделать это можно только так
MathAbs(X-Y) < precision

Для примера в начале ветки precision <= 0.0001
 
Возможно, имеет смысл сделать FAQ...
 

Точно так же глючит и в С/C++. Я сталкивался с этим много раз, но и в данном случае специально проверил это лично, запустив Ваш пример в С++. Если бы это была наша ошибка - мы бы тут же это признали и сегодня же выпустили патч.

То что это ошибка - признано. Исправить можем? можем. Но так как это не наша ошибка, то и исправлять мы не будем.

Я правильно понял?

 
kermit:

Точно так же глючит и в С/C++. Я сталкивался с этим много раз, но и в данном случае специально проверил это лично, запустив Ваш пример в С++. Если бы это была наша ошибка - мы бы тут же это признали и сегодня же выпустили патч.

То что это ошибка - признано. Исправить можем? можем. Но так как это не наша ошибка, то и исправлять мы не будем.

Я правильно понял?

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

Все-же велика сила нежелания учиться у людей.
 
getch:
Возможно, имеет смысл сделать FAQ...
Все равно по нему придется искать. А люди все также будут лениться это делать.

По сути, весь MQL4.community и есть огромный FAQ с очень хорошей поисковой системой. Мы не зря потратили силы на создание морфологического(с учетом словоформ) поисковика и похожие темы. Проблема не в объеме информации, а скорее в нежелании ее использовать.
Причина обращения: