я предпочитаю использовать для сравнения по возможности знаки больше и меньше,
double a; double b; if(a>b) if(a<b) {......} {......}
дабы особо не заморачиватся на проиведение double к определенной разрядности
Vol = 156.00000002; NormVol = NormalizeDouble(Vol,2); 156.00
если вседаки необходимо именно ставнить числа
if(a==b) или if(a!=b) {......} {......}
то сначала я привожу оба числа к единой разрядности после точки
a = NormalizeDouble(Vol1,2); b = NormalizeDouble(Vol2,2); if(a==b) или if(a!=b) {......} {......}
xeon:
А при расчетах в индикаторах Вы используете Normalize и подобные подготовки?то сначала я привожу оба числа к единой разрядности после точки
a = NormalizeDouble(Vol1,2); b = NormalizeDouble(Vol2,2); if(a==b) или if(a!=b) {......} {......}
Просматриваю много кода, учусь программировать и редко где в коде индикатора это встречается. Вот вопрос и возник - как по хорошему-то надо.
VBAG:
Просматриваю много кода, учусь программировать и редко где в коде индикатора это встречается. Вот вопрос и возник - как по хорошему-то надо.
xeon:
А при расчетах в индикаторах Вы используете Normalize и подобные подготовки?то сначала я привожу оба числа к единой разрядности после точки
a = NormalizeDouble(Vol1,2); b = NormalizeDouble(Vol2,2); if(a==b) или if(a!=b) {......} {......}
Просматриваю много кода, учусь программировать и редко где в коде индикатора это встречается. Вот вопрос и возник - как по хорошему-то надо.
независимо индикатор, скрипт или эксперт, нарватся на несоответствие double можно везде, поэтому я стараюсь этого избежать используя NormalizeDouble или используя знаки "<" и ">"
xeon ,
Спасибо за Ваше мнение.
Нормализуйте всегда, и проблем с даблами никогда не будет! ;)
При любом сравнении, любые даблы, и с осознанно выбранной точностью.
Обратите внимание на функцию equal - если ее чуть изменить:
Например, equal( 0.123456784, 0.123456776 ) в первом варианте вернет true, а во втором - false ;)
При любом сравнении, любые даблы, и с осознанно выбранной точностью.
//--- NormalizeDouble double nd( double value, int precision ) { return( NormalizeDouble( value, precision ) ); } //--- MathAbs double abs( double value ) { return( MathAbs( value ) ); } //--- Если value1 равняется value2 до precision знака после запятой, возвращает true, иначе - false. bool equal( double value1, double value2, int precision = 8 ) { return( nd( abs( nd( value1, precision ) - nd( value2, precision ) ), precision ) < nd( MathPow( 0.1, precision ), precision ) ); }
Обратите внимание на функцию equal - если ее чуть изменить:
bool equal( double value1, double value2, int precision = 8 ) { return( nd( abs( value1 - value2 ), precision ) < nd( MathPow( 0.1, precision ), precision ) ); }(убрать нормализацию каждого числа перед сравнением), она будет давать другой результат.
Например, equal( 0.123456784, 0.123456776 ) в первом варианте вернет true, а во втором - false ;)
komposter:
Нормализуйте всегда, и проблем с даблами никогда не будет! ;)
Зато будут проблемы с производительностью. Проблема сравнения чисел с двойной точностью надумана и исходит от элементарного незнания матчасти.
Нормализуйте всегда, и проблем с даблами никогда не будет! ;)
Irtron:
Проблема сравнения чисел с двойной точностью надумана и исходит от элементарного незнания матчасти.
Проблема сравнения чисел с двойной точностью надумана и исходит от элементарного незнания матчасти.
Поясню.
Очевидно, происходит смешивание понятий. Есть тип числа с плавающей точностью, который в intel архитектуре используется для представнения чисел с фиксированной точностью, к которым, в частности, относятся все величины торгового окружения, потому как в процессоре есть специальная молотилка для плавающей арифметики.
На самом деле, числа с фиксированной точностью очень мало отличаются от целых чисел с точки зрения машинного представления. Наличие десятичного знака в этом случае условно. Это свойство широко используется в архитектуре, в которой плавающая арифметика аппаратно не поддерживается, например, в ARMе, получившем распространение благодаря использованию в PDA и смартфонах. Плавающую арифметику там приходится эмулировать довольно тяжелым кодом, что здорово греет процессор и, соответственно, сажает батарею, не говоря уж о скорости выполнения программы. Поэтому везде, где нельзя обойтись целыми числами, используется фиксированный формат. Плавающая точность применяется в самых крайних случаях. Вернее, конечно, должна бы применяться.
Ничто не мешает использовать фиксированную (то бишь целочисленную) арифметику для рыночных величин.
Это не относится к расчетным значениям индикаторов. Там вполне достаточно прямого сравнения. Зачем их сравнивать с какой-то точностью?
Спасибо komposter и Irtron ! Уже решил, что больше ничего не напишут и сел придумывать сам и не видел ваши посты.
Посмотрите пожалуйста, что накропал своей корявой рукой:
//+------------------------------------------------------------------+
bool EqualDouble(double dN1, double dN2,int Digit)
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 == 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool LessDouble(double dN1, double dN2,int Digit) // Если dN1<dN2
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d2-d1 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool MoreDouble(double dN1, double dN2,int Digit) // Если dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
Посмотрите пожалуйста, что накропал своей корявой рукой:
//+------------------------------------------------------------------+
bool EqualDouble(double dN1, double dN2,int Digit)
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 == 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool LessDouble(double dN1, double dN2,int Digit) // Если dN1<dN2
{
double d1 = NormalizeDouble(dN1,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d2-d1 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
bool MoreDouble(double dN1, double dN2,int Digit) // Если dN1>dN2
{
double d1 = NormalizeDouble(dN2,Digit);
double d2 = NormalizeDouble(dN2,Digit);
bool res=false;
res=d1-d2 > 0.0;
return(res);
}
//+------------------------------------------------------------------+
Покритикуйте, пожалуйста.
VBAG:
Посмотрите пожалуйста, что накропал своей корявой рукой:
Вы какие величины пытаетесь сравнивать? Цены, лоты или значения индикаторов?
Посмотрите пожалуйста, что накропал своей корявой рукой:
Irtron:
Я в начале писал: "Пытаюсь выработать "правильный" стиль программирования. "VBAG:
Посмотрите пожалуйста, что накропал своей корявой рукой:
Вы какие величины пытаетесь сравнивать? Цены, лоты или значения индикаторов?Посмотрите пожалуйста, что накропал своей корявой рукой:
А по сути, какая разница, что в даблах лежит-только точность округления Digit будет разная, в зависимости от требований к переменной.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Как известно, от стиля программирования и аккуратности в коде зависит не только правильность расчетов, но и надежность работы написанного кода.
Пишем не игрушки, а потому надежность работы написанной программы является самым первым требованием. Большинство расчетов производится в даблах и корректное сравнение в коде
программы двух вещественных чисел, требует определенного подхода и аккуратности.
Пытаюсь выработать "правильный" стиль программирования. Отсюда вопрос:
Для выражения
double a;
double b;
if(a==b) или if(a!=b)
{......} {......}
разработчики рекомендуют так
//+------------------------------------------------------------------+
//| Функция сранения двух вещественных чисел. |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
{
bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
return(Compare);
}
//+------------------------------------------------------------------+
Корректен ли код?
double a;
double b;
if(a>b) if(a<b)
{......} {......}
Скорей всего, что в общем случае нет. Какой способ корректной проверки избрать?
Какой вообще стиль работы с даблами целесообразнее?
Заранее благодарен всем откликнувшимся.