Reel Tipler (double, float)

Reel tipler (yada kayan noktalı tipler) ondalık kısımları olan değerleri temsil eder. MQL5 dilinde kayan nokta sayıları için iki farklı tip mevcuttur. Bilgisayar hafızasında reel sayıların temsil yöntemi IEEE 754 standardı ile tanımlanır ve platformlardan, işletim sistemlerinden ve programlama dillerinden bağımsızdır.

Tip

Bayt bazında büyüklük

Minimal Pozitif Değer

En büyük değer

C++ Analog

float

4

1.175494351e-38

3.402823466e+38

float

double

8

2.2250738585072014e-308

1.7976931348623158e+308

double

 

double

double gerçek sayı türü 64 bit (1 işaret biti, 11 üs biti ve 52 mantis biti) kaplar.

float

float gerçek sayı türü 32 bit (1 işaret biti, 8 üs biti ve 23 mantis biti) kaplar.

vector

double türünde sayılardan oluşan tek boyutlu dizidir. Veriler için bellek dinamik olarak tahsis edilir. Metotlar kullanılarak vektör özellikleri elde edilebilir ve vektör büyüklüğü değiştirilebilir. Şablon fonksiyonlarında vector<double> girdisi kullanılabilir.

vectorf

Hassasiyet kaybı önemli değilse, vector yerine float türünde sayılardan oluşan tek boyutlu dizi olan vectorf kullanılabilir. Şablon fonksiyonlarında vector<float> girdisi kullanılabilir.

vectorc

complex türünde sayılardan oluşan tek boyutlu dizidir. Karmaşık sayıların işlenmesi içindir. Şablon fonksiyonlarında vector<complex> girdisi kullanılabilir. vectorc türündeki vektörler üzerinde işlemler henüz tanımlanmamıştır.

matrix

double türünde sayılardan oluşan iki boyutlu dizidir. Veriler için bellek dinamik olarak tahsis edilir. Metotlar kullanılarak matris özellikleri elde edilebilir ve matris şekli değiştirilebilir. Şablon fonksiyonlarında matrix<double> girdisi kullanılabilir.

matrixf

Hassasiyet kaybı önemli değilse, matrix yerine float türünde sayılardan oluşan iki boyutlu dizi olan matrixf kullanılabilir. Şablon fonksiyonlarında matrix<float> girdisi kullanılabilir.

matrixc

complex türünde sayılardan oluşan iki boyutlu dizidir. Karmaşık sayıların işlenmesi içindir. Şablon fonksiyonlarında matrix<complex> girdisi kullanılabilir. matrixc türündeki vektörler üzerinde işlemler henüz tanımlanmamıştır.

 

double ismi, bu sayıların çözünürlüğünün float tipli sayıların iki katı olmasından gelir. Çoğu durumda double tipi en uygun olandır. Çoğu durumda ise float sayıların sınırlı çözünürlükleri yetersizdir. float tipinin hala kullanılmasının sebebi bellek tasarrufudur (bu, geniş reel sayı dizileri için önemlidir).

Kayan noktalı sabitler bir tamsayı kısmı, bir nokta (.) ve bir ondalık kısımdan oluşur. Tamsayı ve kesirli kısımlar, ondalık sayı dizileridir.

Örnekler:

   double a=12.111;
   double b=-956.1007;
   float  c =0.0001;
   float  d =16;

Reel sabitleri yazmanın bilimsel bir yolu vardır ve bu kayıt yöntemi çoğunlukla geleneksel yöntemden daha derli topludur.

Örnek:

   double c1=1.12123515e-25;
   double c2=0.000000000000000000000000112123515// noktadan sonra 24 sıfır
   
   Print("1. c1 =",DoubleToString(c1,16));
   // Sonuç: 1. c1 = 0.0000000000000000
   
   Print("2. c1 =",DoubleToString(c1,-16));
   // Sonuç: 2. c1 = 1.1212351499999999e-025
 
   Print("3. c2 =",DoubleToString(c2,-16));
   // Sonuç: 3. c2 = 1.1212351499999999e-025

Reel sayıların ondalık notasyon kullanılırken bellek üzerinde ikili sistemde ve sınırlı kesinlikle depolandığı hatırlanmalıdır. Bu, ondalık sistemde tam olarak temsil edilen birçok sayının, ikili sistemde sadece sonsuz bir kesir olarak yazılmasını açıklar.

Örneğin, 0.3 ve 0.7 sayıları, bilgisayarda sonsuz bölümlerle temsil edilirken, 0.25 tam olarak saklanır, çünkü ikinin kuvvetini temsil eder.

Bu yüzden, iki reel sayının eşitliklerinin kontrolü için karşılaştırılma yapılması tavsiye edilmez; böyle bir karşılaştırma doğru değildir.

Örnek:

void OnStart()
  {
//---
   double three=3.0;
   double x,y,z;
   x=1/three;
   y=4/three;
   z=5/three;
   if(x+y==z) 
      Print("1/3 + 4/3 == 5/3");
   else 
      Print("1/3 + 4/3 != 5/3");
// Sonuç: 1/3 + 4/3 != 5/3
  }

Eğer hala iki reel sayıyı karşılaştırmak istiyorsanız bunu iki şekilde yapabilirsiniz. İlk yol, iki sayı arasındaki farkı karşılaştırmanın doğruluğunu belirleyecek küçük bir meblağ ile karşılaştırmaktır.

Örnek:

bool EqualDoubles(double d1,double d2,double epsilon)
  {
   if(epsilon<0) 
      epsilon=-epsilon;
//---
   if(d1-d2>epsilon) 
      return false;
   if(d1-d2<-epsilon) 
      return false;
//---
   return true;
  }
void OnStart()
  {
   double d_val=0.7;
   float  f_val=0.7;
   if(EqualDoubles(d_val,f_val,0.000000000000001)) 
      Print(d_val," eşittir ",f_val);
   else 
      Print("Farklı: d_val = ",DoubleToString(d_val,16),"  f_val = ",DoubleToString(f_val,16));
// Sonuç: Farklı: d_val= 0.7000000000000000   f_val= 0.6999999880790710
  }

Yukarıdaki örnekteki epsilon değerinin, ön tanımlı sabit DBL_EPSILON değerinden küçük olamayacağını not edin. Bu sabitin değeri 2.2204460492503131e-016 sayısına eşittir. Float tipine karşılık gelen sabit FLT_EPSILON = 1.192092896e-07 sayısıdır. Bunlar şu anlama gelir: Bu değer, 1.0 + DBL_EPSILON koşulunu sağlayan en düşük değerdir! = 1.0 (float tipli sayılar için 1.0 + FLT_EPSILON! = 1.0).

İkinci yol, iki reel sayının normalleştirilmiş farklarını sıfırla karşılaştırmayı önerir. Normalleştirilmiş farkın sıfır ile karşılaştırılması anlamsızdır. Normalleştirilmiş sayılarla yapılan tüm matematiksel işlemler normalize olmayan sonuçlar verirler.

Örnek:

bool CompareDoubles(double number1,double number2)
  {
   if(NormalizeDouble(number1-number2,8)==0) 
      return(true);
   else 
      return(false);
  }
void OnStart()
  {
   double d_val=0.3;
   float  f_val=0.3;
   if(CompareDoubles(d_val,f_val)) 
      Print(d_val," equals ",f_val);
   else 
      Print("Farklı: d_val = ",DoubleToString(d_val,16),"  f_val = ",DoubleToString(f_val,16));
// Sonuç: Farklı: d_val= 0.3000000000000000   f_val= 0.3000000119209290
  }

Matematiksel yardımcı işlemcinin bazı işlemleri geçersiz reel sayı ile sonuçlanabilir. Böyle bir sonuç matematiksel işlemlerde ve karşılaştırmalarda kullanılamaz, çünkü geçersiz reel sayılarla yapılan işlemlerin sonucu tanımsızdır. Örneğin, arcsin(2) değerini hesaplamaya çalıştığımızda sonuç negatif sonsuz olur.

Örnek:

   double abnormal = MathArcsin(2.0);
   Print("MathArcsin(2.0) =",abnormal);
// Sonuç:  MathArcsin(2.0) = -1.#IND

Eksi sonsuzun yanında, artı sonsuz ve NaN (not a number: bir sayı değil) bulunmaktadır. Sayının geçersiz olup olmadığını öğrenmek için MathIsValidNumber() fonksiyonunu kullanabilirsiniz. IEEE standardına göre, bunlar özel makine temsiline sahiptirler. Örneğin, double tip için artı sonsuz değeri 0x7FF0 0000 0000 0000 şeklinde bit temsiline sahiptir.

Örnekler:

struct str1
  {
   double d;
  };
struct str2
  {
   long l;
  };
 
//--- Başlat
   str1 s1;
   str2 s2;
//---
   s1.d=MathArcsin(2.0);        // -1.#IND geçersiz sayısını al
   s2=s1;
   printf("1.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0xFFFF000000000000;     // geçersiz sayı -1.#QNAN
   s1=s2;
   printf("2.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FF7000000000000;     // en büyük sayı-olmayan SNaN
   s1=s2;
   printf("3.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FF8000000000000;     // en küçük sayı-olmayan QNaN
   s1=s2;
   printf("4.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FFF000000000000;     // en büyük sayı-olmayan QNaN
   s1=s2;
   printf("5.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FF0000000000000;     // Artı sonsuz 1.#INF ve en küçük sayı-olmayan SNaN
   s1=s2;
   printf("6.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0xFFF0000000000000;     // Eksi sonsuz -1.#INF
   s1=s2;
   printf("7.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x8000000000000000;     // Negatif sıfır -0.0
   s1=s2;
   printf("8.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x3FE0000000000000;     // 0.5
   s1=s2;
   printf("9.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x3FF0000000000000;     // 1.0
   s1=s2;
   printf("10.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FEFFFFFFFFFFFFF;     // En büyük normalize sayı (MAX_DBL)
   s1=s2;
   printf("11.  %.16e %I64X",s1.d,s2.l);
//---
   s2.l=0x0010000000000000;     // En küçük normalize sayı (MIN_DBL)
   s1=s2;
   printf("12.  %.16e %.16I64X",s1.d,s2.l);
//---
   s1.d=0.7;                    // 0.7 sayısını göster - sonsuz fraksiyon
   s2=s1;
   printf("13.  %.16e %.16I64X",s1.d,s2.l);
/*
1.  -1.#IND00 FFF8000000000000
2.  -1.#QNAN0 FFFF000000000000
3.   1.#SNAN0 7FF7000000000000
4.   1.#QNAN0 7FF8000000000000
5.   1.#QNAN0 7FFF000000000000
6.   1.#INF00 7FF0000000000000
7.  -1.#INF00 FFF0000000000000
8.  -0.000000 8000000000000000
9.   0.500000 3FE0000000000000
10.  1.000000 3FF0000000000000
11.  1.7976931348623157e+308 7FEFFFFFFFFFFFFF
12.  2.2250738585072014e-308 0010000000000000
13.  6.9999999999999996e-001 3FE6666666666666 
*/

Ayrıca Bakınız

DoubleToString, NormalizeDouble, Nümerik Tipli Sabitler