Fiyat != Fiyat ? - sayfa 7

 

WHRoeder: bu kod iyi (özellikle "eklendi" ve "varsayılan"ı kontrol edin )? Ayrıca, bu konuyu ziyaret edip son sayfaya gidenler için kolay bir son başvuru kaynağı olabilir (benim yaptığım gibi)

 #define LT     0
#define GT     1
#define GTE   2
#define LTE   3
#define EQ     4
#define NEQ   5

bool doublecomp( double a, int type, double b){
   // See https://forum.mql4.com/45053/page4
   // 0 compare doesn't need this function
   switch (type){
     case LT: return (b-a> Point / 2 .);
     case GT: return (a-b> Point / 2 .);
     case GTE: return (a-b>- Point ); // Added
     case LTE: return (b-a>- Point ); // Added
     case EQ: return (!( MathAbs (a-b)> Point / 2 .));
     case NEQ: return ( MathAbs (a-b)> Point / 2 .);
     default : return (- 1 ); // Added - needed to avoid compile error about not all control paths returning a value
  }
}
 

O kod doğru değil.

Eşitlik için karşılaştırma yapmak için if( !MathAbs( a - b ) > Point/2) nasıl kullanılabilir? Bu size 1.4999 == 1.5000

 
SDC : Eşitlik için karşılaştırma yapmak için if( !MathAbs( a - b ) > Point/2) nasıl kullanılabilir? Bu size 1.4999 == 1.5000
  1. değil
    if ( ! ( MathAbs ( a     -  b    ) > Point / 2 ) ) be used to compare for equality? That would tell you 1.4999 == 1.5000
    if ( ! ( MathAbs ( 1.4999 - 1.5000   > 0.00005   )
    if ( ! ( 0.0001                    > 0.00005   )
    if ( ! ( true                                 )
    if ( false                                   ) 1.4999 is NOT equal to 1.5000
  2. Ve bir PM'de Roel13'e GEQ/LEQ'nun -Point /2 olması gerektiğini belirtmiştim ama o yazıyı düzenlemedi.
  3. Ve daha önce yayınladığım gibi, sadece eşitlik/eşitsizlik önemliyse bu tür saçmalıklar hakkında endişelenmeniz gerekir. Bir mumun yüksekliğinin üzerinde açmak istiyorsanız, (yuvarlama nedeniyle) tam olarak yüksekte tetiklenmesinin bir önemi var mı? Hayır ise, sadece teklif > yüksek[] kullanın.
 

kullanırım

 if ( NormalizeDouble (price1-price2, Digits )== 0 )


veya gerçek fiyatlar olmayan çiftler için daha yüksek bir hassasiyet

 if ( NormalizeDouble (value1-value2, 8 )== 0 )
 
SDC : kullanıyorum
 if ( NormalizeDouble (price1-price2, Digits )== 0 )
İlk gönderiyi okuyun ve bunun neden iyi bir fikir olmadığını öğreneceksiniz.
 

Raptors bu kod hakkında yayın yapıyor

 double TestValue = iClose ( NULL , 0 , 0 );
   
if (TestValue != NormalizeDouble (TestValue, Digits ) ) //not equal

Yani kullanırsanız,

 double TestValue = iClose ( NULL , 0 , 0 );

if(NormalizeDouble(TestValue - iClose(NULL,0,0),Digits)==0) // they are considered equal

Bu yöntemi çeşitli şekillerde test ettim, beklenen veya istenen sonucu getirmeyecek bir senaryo bulamadım.
 

Son kod... Teşekkürler WHRoeder

 #define LT     0
#define GT     1
#define GTE   2
#define LTE   3
#define EQ     4
#define NEQ   5

bool ComparePrice( double a, int type, double b){
   // See https://forum.mql4.com/45053/page4
   // 0 compare doesn't need this function
   switch (type){
     case LT: return (b-a> Point / 2 .);
     case GT: return (a-b> Point / 2 .);
     case GTE: return (a-b>-Point/2.);
    case LTE: return (b-a>-Point/2.);
    case EQ: return (!( MathAbs (a-b)> Point / 2 .));
     case NEQ: return ( MathAbs (a-b)> Point / 2 .);
  }
  return (- 1 );
}


Ve belki de fiyat olmayan tüm diğer çiftleri karşılaştırmak için ikincil bir işlev...

 bool CompareNormal( double a, int type, double b){
   // With thanks https://forum.mql4.com/45053/page4
   // 0 compare doesn't need this function
   switch (type){
     case LT: return (b-a> 0.0000000000000000000000000000001 );
     case GT: return (a-b> 0.0000000000000000000000000000001 );
     case LTE: return (b-a>- 0.0000000000000000000000000000001 );
     case GTE: return (a-b>- 0.0000000000000000000000000000001 );
     case EQ: return (!( MathAbs (a-b)> 0.0000000000000000000000000000001 ));
     case NEQ: return ( MathAbs (a-b)> 0.0000000000000000000000000000001 );
  }
   return (- 1 );
}


Karşılaştırma için küçük sayıların kullanılmasıyla ilgili olarak ayrıca bkz. 'MQL4 Reference > Language Basics > Data Types > Real Types (double, float)'.

Belki birisi expon'da 0.00...1 yazmayı daha iyi biliyordur

 
Roel13 : Belki birisi expon'da 0.00...1 yazmayı daha iyi biliyordur
 // case LT: return(b-a>0.0000000000000000000000000000001);
// case LT: return(b-a>1.0e-30);
Gerçek Tiplere Bakın (double, float) - MQL4 Documentation
Yukarıdaki örnekte epsilon değerinin önceden tanımlanmış DBL_EPSILON sabitinden daha az olamayacağına dikkat edilmiştir. Bu sabitin değeri 2.2204460492503131e-016'dır.
Yine, eşitlerin/eşitliklerin önemli olduğu durumlar dışında bunların hiçbiri gerekli değildir . Örneğin, bir önceki zirvenin üzerinde açın, yuvarlama nedeniyle yüksekte açmak istemezsiniz.
 

Bu yüzden, potansiyel olarak "// 0 karşılaştırmanın bu işleve ihtiyacı yok" ile bağlantılı olarak bulduğum ilginç bir şey daha var.

Belki sadece en son sürümlerde bir hata, emin değilim. 0 ile karşılaştırma artık doğru çalışmıyor. Düşmanca olmayan bir şeye başvurmak zorunda kaldım;

sonuç=(int(sonuç*100)/100.0); // Çözünürlük 2 basamak

Sadece 0 değerlerinin gerçekten 0 değer olarak sonuçlandığından emin olmak için.

WHRoeder, teşekkürler. Daha fazla çalışma gerekli :)

 

Bence bu konu çok fazla gereksiz karmaşıklıkla işleniyor.

Programcınızın hayatını her zaman mümkün olduğunca kolaylaştırmaya çalışın. İkili karşılaştırmalarınıza ihtiyaç duyduğunuz sınıflarda tanımlar yazın (veya gerçekten yapmanız gerekiyorsa yöntemlerle devam edin):

 // add more floating point zeros if you need a higher precision
#define isZero(x) ( fabs (x) < 0.000000001 )
#define isEqual(x,y) ( fabs (x-y) < 0.000000001 )

İki dubleyi karşılaştırmanız gerektiğinde, bunu aşağıdaki gibi bir durumda kullanın:

 if (isEqual(myFirstDouble, mySecondDouble))
{
   // first and second doubles are considered equal
   // do something
}

Bir çiftin sıfır olup olmadığını (veya sıfıra çok, çok yakın) görmek istiyorsanız, aşağıdaki gibi bir koşul kullanın:

 if (isZero(myDouble))
{
   // myDouble is considered zero
   // do something
}


Bir yan notta, bölümlerden bahseden birçok gönderi gördüğüm için:

Kapsülleme ile, bazı yardımcı yöntemlere "dış kaynaklı" olan kodun maliyetlerini unutma eğilimindeyiz. Kendinize bölümlerin hesaplama açısından çok pahalı olduğunu hatırlatın! Özellikle, fayda sınıflarında bir yerde nice fayda yöntemlerine sarıldığında, bunları göstergelerde veya EA'larda her yerde kullanmaya başlıyoruz ve hangi hesaplama adımlarını gerçekleştirdiklerini çoktan unuttuk. Strateji test cihazını kullanırken, özensizliğimiz için çok fazla gereksiz zaman ödüyoruz.

Temel kural : Toplama ve çıkarma işlemleri, çarpma ve bölme işlemlerinden çok daha hızlıdır. Bölme işlemi en yüksek hesaplama süresini alır. Bölümleri optimize edin - mümkün olan her yerde! Payda bu döngüdeki gibi sabit ise...

 for ( int i= 0 ; i < rates_total; i++)
{
     // ...
     double fraction = someNumeratorValue / 100 ;
     // ...
}

sonra payda x'i ters çevrilmiş değeri 1/x ile değiştirin :

 for ( int i= 0 ; i < rates_total; i++)
{
     // ...
     double fraction = 0.01 * someNumeratorValue; // replace a denominator with it's inverted value, if possible.
     // ...
}

Ayrıca, bir bölmenin sonucu her zaman aynıysa, o zaman hesaplamayı bir kez yapın ve sonucu bir değişkene kaydedin, böylece onu kodunuzun her yerinde (örneğin döngülerde) kullanabilirsiniz:

 double tradesPerDay = totalTradesPerYear/ 365 ;

for ( int i= 0 ; i < rates_total; i++)
{
     // use precomputed tradesPerDay rather than computing the division here.
}

Şerefe,

AT