Правильный перевод double в int - страница 6

 
Nikolai Semko:

Такой аналог NormalizeDouble работает в пару раз быстрее:

У меня показывает одинаковую скорость.

ЗЫ данный аналог пока не проверял на полное соответствие

Открою секрет: NormalizeDouble в MT4 и MT5 - разные функции. Здесь мой вариант.


ЗЫ Для проверки корректности сделайте так

      s+=12345.01548639670241547;
Библиотеки: Price_Compare
Библиотеки: Price_Compare
  • 2016.10.19
  • www.mql5.com
Price_Compare: Автор: fxsaber...
 
fxsaber:

У меня показывает одинаковую скорость.

Открою секрет: NormalizeDouble в MT4 и MT5 - разные функции. Здесь мой вариант.

ЗЫ Для проверки корректности сделайте так

Спасибо.  Ваш вариант гораздо лучше.

Я его чуть отредактировал, чтобы он полностью соответствовал NormalizeDouble, т.к. в справке ошибка. Реально digits не 0...8, а 0...11. Так же достаточно добавлять (отнимать) 0.5, а не (0.5 + 1.0e-7).

double MyNormalizeDouble(const double Value,const uint digits)
  {
   static const double Points[]={1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10};
   const double point=digits>10 ? 1e11 : Points[digits];
   const long Integer=(long)Value; // чтобы не создавать крайне медленный относительный epsilon
   return((long)((Value > 0) ? (Value - Integer) * point + 0.5 : (Value - Integer) * point - 0.5) / point + Integer);
  }

Но выигрыша, действительно, никакого нет. Поэтому смело можно продолжать пользоваться стандартной функцией.

Файлы:
 
Nikolai Semko:

Спасибо.  Ваш вариант гораздо лучше.

Я его чуть отредактировал, чтобы он полностью соответствовал NormalizeDouble, т.к. в справке ошибка. Реально digits не 0...8, а 0...11. Так же достаточно добавлять (отнимать) 0.5, а не (0.5 + 1.0e-7).

NormalizeDouble(1.15, 1)

Но выигрыша, действительно, никакого нет. Поэтому смело можно продолжать пользоваться стандартной функцией.

Пару процентов выигрыша можно использовать при написании своего Тестера, например.

 
fxsaber:
NormalizeDouble(1.15, 1)

Согласен, что касается  части соответствия оригинальной функции.
Но тогда оригинальная функция врет:

NormalizeDouble  (1.44999999,1);  // 1.5
 
Nikolai Semko:

Согласен, что касается  части соответствия оригинальной функции.
Но тогда оригинальная функция врет:

Да, врет. Потому что в оригинале указан

#define HALF_PLUS (0.5 + 1.0e-7)

Если заменить 7 на 11, то врать не будет. Но дело в том, что тогда можно будет предоставить такой контрпример 1.449999999999. А надо ли?

 
fxsaber:

Да, врет. Потому что в оригинале указан

Если заменить 7 на 11, то врать не будет. Но дело в том, что тогда можно будет предоставить такой контрпример 1.449999999999. А надо ли?

Согласен. 

Здесь я вижу проблему в правиле округления.
Вообще математическое правило округления 0.5 в большую по модулю сторону  это неоднозначный вопрос. Когда идет речь о применении в финансовой сфере, то на мой вгляд более логичным является банковское округление, когда округляется до ближайшего чётного, чтобы не происходило накопление ошибки.