Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 144

 
Igor Makanu :

NaN için ayrıca kontrol etmeniz gerekir

Bu normal bir numara. Kontrol basittir - neye böldüğünüz, ardından sıfır olup olmadığını kontrol edin.

 
fxsaber :

Bu normal bir numara. Kontrol basittir - neye böldüğünüz, ardından sıfır olup olmadığını kontrol edin.

ancak bu kodda null olup olmadığını kontrol etmezsiniz:

 // Неправильно написанная функция.
double WrongFunc( const double Num )
{
   return (Num ? 1 / ( 0.1 * Num) : 0 );
}

ifade Sayı ? MQL'de, çift 8 baytta 0x00000000 00000000 değeri yoksa bu doğru olacaktır.

başka bir durumda bu ifade ( Num ? ) doğru olacaktır


Ayın başında MQL'de bool kontrolü oluşturmama hakkında bir tartışma başlattım - cevap şu ki, veri kaybı yok, bu yüzden gerekli değil - bu aynı problem, ifadeyi NaN'ye bölmeyi deneyebilirsiniz - çift bayt boş olmayacak mı?


Şu anda test edemiyorum, ancak şuna benziyor:

 // Неправильно написанная функция.
double WrongFunc( const double Num )
{
   return (Num && !(Num!=Num) ? 1 / ( 0.1 * Num) : 0 );
}
 
Igor Makanu :

ancak bu kodda null olup olmadığını kontrol etmezsiniz:

Şu anda test edemiyorum, ancak şuna benziyor:

Çalışmayacak. Kilitlenme örneğinde, Num normal bir sayıdır. bool iş dışı.

 
fxsaber :

Çalışmayacak. Kilitlenme örneğinde, Num normal bir sayıdır. bool iş dışı.

kontrol edilen NaN araması

 //+------------------------------------------------------------------+
void OnStart ()
{
   union ULongTODouble {
       ulong ul;
       double d;
   } ULongDouble;

   ulong i = 0xFFFFFFFFFFFFFFFF ;
   while (i > 0 && ! IsStopped ()) {
      ULongDouble.ul = i;
       if (ULongDouble.d != ULongDouble.d) Print ( "NaN, i = " , i);
      i--;
   }

}
//_______________________________________________________________________

gerçekten MQL5'te çalışıyor, döngüyü sıfırdan başlatabilirsiniz, daha uzun süre beklemeniz gerekecek

burada, genel olarak, sorunuz çift doğrulukla ilgili bir sorudur - genellikle belirli bir işlemci türüne bağlıdır, bu nedenle yukarıda hatanın yeniden oluşturulmadığına dair yorumlar vardı


UPD:

şu şekilde sonuçlandırmak daha iyidir:

 if (ULongDouble.d != ULongDouble.d) Print ( "NaN, d = " , ULongDouble.d); // tst1 (EURUSD,H1)	NaN, d = -nan
 
Hmm, peki ya çiftleri sıfıra bölerken bir istisna atılır? İnf olurdu, bir tür çöp.
 
Igor Makanu :

burada, genel olarak, sorunuz çift doğrulukla ilgili bir sorudur - genellikle belirli bir işlemci türüne bağlıdır, bu nedenle yukarıda hatanın yeniden oluşturulmadığına dair yorumlar vardı

Herhangi birinde tekrarlanabilir. Dürüst olmak gerekirse, bu konu hakkında neden bu kadar çok konuşma yapıldığını anlamıyorum. Sıfır olmayan iki sayıyı çarparak sıfır elde ettik. Sihir yok.


Herkes bu kodu anlıyor mu?

 void OnStart ()
{
   double d = 0.5 ;  
   int Count = 1 ;
  
   while (d *= d)
    Count <<= 1 ;
    
   Print (Count);
}


d sıfır olduğunda kesinlikle benzer bir durum vardır.

 
fxsaber :

Sihir yok.

işte sihir, şu şekilde basılmıştır:

 void OnStart ()
{
   union ULongTODouble {
       ulong ul;
       double d;
   } ULongDouble;

   ulong nan = 18446744073708624091 ;
   ULongDouble.ul = nan;
   
   Print ( "ULongDouble.d != ULongDouble.d " , ULongDouble.d != ULongDouble.d);
   double d_value = 0.1 * ULongDouble.d;
   bool b_value = d_value;
   Print ( "b_value =  " , b_value);
   Print ( "d_value =  " , d_value);
   Print ( "1 / d_value =  " , 1 / d_value);

}
//_______________________________________________________________________

2019.10.28 16:25:28.643 tst1 (EURUSD,H4) ULongDouble.d != ULongDouble.d doğru

2019.10.28 16:25:28.643 tst1 (EURUSD,H4) b_değeri = doğru

2019.10.28 16:25:28.643 tst1 (EURUSD,H4) d_değeri = nan

2019.10.28 16:25:28.667 tst1 (EURUSD,H4) 'tst1.mq5' içinde sıfır bölme (28,31)



fxsaber :

d sıfır olduğunda kesinlikle benzer bir durum vardır.

Sıfırdan bahsetmiyorum, örneğinizde 0.1 * Num ? bu bool - o zaman 8 çift baytta en az bir bit olması aptalca

0.1 * Num double olduğunda , hassasiyet kaybı durumunda Nan'a uçabilir ve sıfır bölme elde edebilirsiniz.

 
İşte bunu anlamadım.
 #include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

void OnStart ()
{
   double Num = 0 ;
  
  _W(Num) = ( uchar ) 1 ;
  
   Print (Num < DBL_MIN ); // true
   Print ( DBL_MIN );       // 2.225073858507201e-308
   Print (Num);           // 4.940656458412465e-324
}


DBL_MIN, minimum pozitif çift değil.

 
fxsaber :

DBL_MIN, minimum pozitif çift değil.

İkinci sayının geçersiz bir çift biçimi olduğunu düşünüyorum, ancak hem baskıda hem de işlemlerde hala doğrulanıyor. belki de bu yüzden dağılıyor.

 
fxsaber :
İşte bunu anlamadım.


DBL_MIN, minimum pozitif çift değil.

DBL_MIN ile NaN'yi iyi karşılaştırın - sonuç bool olacak mı?

ve 1.0'ı sayı olmayan bir sayıya bölersek, yukarıda belirtildiği gibi bir istisna elde ederiz.

genel olarak, geliştiricilerin birçok kez yazdıkları, daha fazla/daha az/eşit ile iki katına karşılaştırmanın doğru olmadığı - bu doğrudur, bazen sayı olmayan bir sayıya basabilirsiniz ve karşılaştırmanın sonucu tahmin edilemez olacaktır.