Ошибки, баги, вопросы - страница 2821

 
Igor Makanu:

нормализация это не округление 

На пять с плюсом знаю теорию, как работать с double и прочее. Алгоритм NormalizeDouble содержит ошибку. Поднятая тема только косвенно касается сравнения даблов.

 
fxsaber:

Повторяю свой вопрос.

На снимке видно значение не нормализованной переменной n и нормализованной m и на сколько они отличаются. Но если вы хотите сравнивать стринги, то это уже ваше предпочтение.

fxsaber:

На пять с плюсом знаю теорию, как работать с double и прочее. Алгоритм NormalizeDouble содержит ошибку. Поднятая тема только косвенно касается сравнения даблов.

Здесь точно без того объяснения Семко не обойтись.
 
NormalizeDouble - это просто определенный алгоритм, который применяется к double-числу. К сожалению, в нем ошибка. Если поправят, ошибка исчезнет. От этого double-представления всех остальных никак не поменяются.
 
fxsaber:

 Алгоритм NormalizeDouble содержит ошибку. 

да

кажется A100 писал об этом

но разработчики с момента появления MQL придерживаются этой "особенности", увы


fxsaber:
 Если поправят, ошибка исчезнет. 
думаю появятся другие баги и будет очень много шума )))
 
Igor Makanu:

думаю появятся другие баги и будет очень много шума )))

Не появятся, т.к. почти все сравнивают даже нормализованные даблы через нормализацию. Т.е. ставят ее куда попало.


Правильная нормализация всегда должна давать true в этом условии.

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

 
fxsaber:
NormalizeDouble - это просто определенный алгоритм, который применяется к double-числу. К сожалению, в нем ошибка. Если поправят, ошибка исчезнет. От этого double-представления всех остальных никак не поменяются.
Да вроде тут дело не в функции, а в том, что константы не нормализуются компилятором (хотя следовало бы).
Это же касается и преобразования string в double.
 
Alexey Navoykov:
Да вроде тут дело не в функции, а в том, что константы не нормализуются компилятором (хотя следовало бы).
Это же касается и преобразования string в double.

Тогда одни те же константы в DLL и MQL будут не совпадать.

 
fxsaber:

Тогда одни те же константы в DLL и MQL будут не совпадать.

Тоже верно. Да и к тому же любая нормализация - это потеря точности, поэтому я пожалуй погорячился с нормализацией констант.
В общем данная проблема, на мой взгляд, не имеет однозначного решения.  Хотя по сути это не такая уж и проблема.
 
Alexey Navoykov:
Тоже верно. Да и к тому же любая нормализация - это потеря точности, поэтому я пожалуй погорячился с нормализацией констант.
В общем данная проблема, на мой взгляд, не имеет однозначного решения.  Хотя по сути это не такая уж и проблема.

Просто подправить текущий алгоритм нормализации.

 
fxsaber:

Просто подправить текущий алгоритм нормализации.

void OnStart() {
   double d1=1.79435;
   double d2=NormalizeDouble(1.79435,5);
   Print(d1==d2);
   Print(is_equal(d1,d2,_Point/2));
}
//+------------------------------------------------------------------+
bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}

даже не знаю, является ли это ошибкой алгоритма.
Действительно, нельзя сравнивать double. Просто жёсткое правило.
Или, как говорит Слава, через эпсилон или через умножение (например на 1/_Point) с преобразованием в int c округлением.

Только округление не через штатные round(), ceil(), floor() т.к. они тоже возвращают double.

А через эти, тем более они работают быстрее штатных:

int Ceil (double x) {return (x-(int)x>0)?(int)x+1:(int)x;}
int Round(double x) {return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) {return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x;}

Проще и быстрее, конечно же, через эпсилон:

bool is_equal(double d1, double d2, double e=0.000000001) {return fabs(d1-d2)<e;}
Причина обращения: