Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
void OnStart()
{
const double d = 5.4555;
int digits = 3;
Print( d, "->", MathRound( d, digits ), "->", ::NormalizeDouble( d, digits ));
}
Вот именно из-за этого и HALF_PLUS! Теперь вспомнил, так было изначально
Надо бы проверочный скрипт похитрее сделать, но лень пока. Здесь Ренат распинался, как надо сравнивать. А у @Quantum, действительно, ошибка.
Вообще Math::MathRound какая то не предсказуемая функция
void OnStart()
{
const double d1 = 5.5555,
d2 = 5.4555;
int digits = 3;
Print( d1, "->", MathRound( d1, digits ), "->", ::NormalizeDouble( d1, digits ));
Print( d2, "->", MathRound( d2, digits ), "->", ::NormalizeDouble( d2, digits ));
}
Результат:
5.5555->5.556->5.556
5.4555->5.455->5.456
А чем d1 принципиально отличается от d2?
А чем d1 принципиально отличается от d2?
В двоичной системе счисления колоссально отличаются.
0.5 == 2^(-1) .
0.05 == 2^(-x), где x - что-то страшное.
Вообще Math::MathRound какая то не предсказуемая функция
Быстрой не знаю, но быстрее написать не сложно.
Они уже ускорили (сравнивал на x32) - проверьте пожалуйста ::NormalizeDouble на x64
Вчера проверял. Мой вариант на 10% быстрее на x64.
10% - не считается. По сравнению с Math::MathRound разница в несколько раз
void OnStart()
{
const double d = 9.305703909421064;
const int dd = 3;
const int ii = 32768*64*4;
double d12;
double d23;
const int time1 = GetTickCount();
for ( int i = 0; i < ii; i++ ) d12 = MathRound( d, dd );
const int time2 = GetTickCount();
for ( int i = 0; i < ii; i++ ) d23 = NormalizeDouble( d, dd );
const int time3 = GetTickCount();
Print( time2-time1, "ms->", time3-time2, "ms" );
printf( "", d12, d23 );
}
10% - не считается. По сравнению с Math::MathRound разница в несколько раз
void OnStart()
{
const double d = 9.305703909421064;
const int dd = 3;
const int ii = 32768*64*4;
double d12;
double d23;
const int time1 = GetTickCount();
for ( int i = 0; i < ii; i++ ) d12 = MathRound( d, dd );
const int time2 = GetTickCount();
for ( int i = 0; i < ii; i++ ) d23 = NormalizeDouble( d, dd );
const int time3 = GetTickCount();
Print( time2-time1, "ms->", time3-time2, "ms" );
printf( "", d12, d23 );
}
Это если использовать мой MathRound. Только ноль будет всегда, каким бы большим не задали ii - компилятор вырезает этот for.
Ренат давал методу подробно, как нужно правильно мерять скорость, когда оптимизатор очень умен.
Вот тест
double MathRound( const double Value, const uint digits )
{
static const double Points[] = {1.0e+0, 1.0e+1, 1.0e+2, 1.0e+3, 1.0e+4, 1.0e+5, 1.0e+6, 1.0e+7, 1.0e+8, 1.0e+9, 1.0e+10, 1.0e+11, 1.0e+12, 1.0e+13, 1.0e+14, 1.0e+15, 1.0e+16};
const double point = (digits > 16) ? 1.0e+16 : Points[digits];
const long Integer = (long)Value; // чтобы не создавать крайне медленный относительный epsilon
return((long)((Value > 0) ? (Value - Integer) * point + HALF_PLUS : (Value - Integer) * point - HALF_PLUS) / point + Integer);
}
ulong BenchStandard(const int Amount=1.0e8)
{
double Price=1.23456;
const double point=0.00001;
const ulong StartTime=GetMicrosecondCount();
//---
for(int i=0; i<Amount;i++)
{
Price=NormalizeDouble(Price+point,2+(i&15));
}
Print("Result: ",Price); // специально выводим результат, чтобы цикл не оптимизировался в ноль
//---
return(GetMicrosecondCount() - StartTime);
}
#include <Math\Stat\Math.mqh>
ulong BenchCustom(const int Amount=1.0e8)
{
double Price=1.23456;
const double point=0.00001;
const ulong StartTime=GetMicrosecondCount();
//---
for(int i=0; i<Amount;i++)
{
Price=MathRound(Price+point,2+(i&15));
}
Print("Result: ",Price); // специально выводим результат, чтобы цикл не оптимизировался в ноль
//---
return(GetMicrosecondCount() - StartTime);
}
void OnStart(void)
{
Print("Standard: ",BenchStandard()," msc");
Print("Custom: ",BenchCustom()," msc");
}
Результат
Custom: 5689482 msc
Result: 1.23013
Standard: 1653102 msc
Result: 1.23013
Custom: 1479310 msc
Выделенное - это мой MathRound, другой Custom - Quantum. Поэтому и говорю о 10%.
А вот так это же выглядит на MT4
2016.12.16 23:15:03.841 MathRound EURUSD,M1: Result: 1.23013
2016.12.16 23:15:00.819 MathRound EURUSD,M1: Standard: 3549950 msc
2016.12.16 23:15:00.819 MathRound EURUSD,M1: Result: 1.23013
2016.12.16 23:14:44.102 MathRound EURUSD,M1: Custom: 10329660 msc
2016.12.16 23:14:44.102 MathRound EURUSD,M1: Result: 1.23013
Т.е. MT5 в два раза быстрее MT4 на этом тесте.
x32 выполняет цикл без лишней самодеятельности. Соотношения у меня примерно такие же получились