Ada Programlama Dili Temelleri

Ek3

Gerçek Sayı Tipleri İçin Öntanımlı Giriş/Çıkış Prosedürleri

(Standart Giriş/Çıkış Ortamı Uygulamaları)

Ek-3 Sayfa 2

Ada.Text_IO Öntanımlı Paketinde Gerçek Sayıların Giriş/Çıkış Prosedürlerinin Tanıtımı

Ada öntanımlı program paketi Ada.Text_IO gerçek sayı tipleri için, stanaart ve dosya ortamlarından veri giriş/çıkışkarına yardımcı olacak prosedürleri içerir. Burada sadece standart (klaye/ekran) giriş çıkış prosedürleri üzerinde duracağız. Ada programlama dilinde gerçek sayı tipleri, Float_IO, Fixed_IO ve Decimal_IO tipleridir. Ada Standard paketinde tanımlanmış olan bu progenitor tiplerin her birisi için, Ada.Text_IO paketinde özel alt paketler tanımlanmıştır. Burada örnek olarak Ada_Text_IO paketinin generik Float_IO alt paketini inceleyeceğiz. Ada.Text_IO_Float_IO generik alt paketinde yapılamış olan tanımlamalar diğer progenitor gerçek sayı tiplerinin generik paketlerinde aynen tekrarlanmıştır.

Ada.Text_IO paketinde Float_IO alt paketinin başlangıcında aşağıdaki tanım yapılmıştır.

   generic
      type Num is  digits <>;
   package Float_IO is
      Default_Fore :  Field := 2;
      Default_Aft  :  Field := Num'Digits-1;
      Default_Exp  :  Field := 3;

Burada Num bir generik tip olarak tanımlanmıştır ve bunu yerine Float, Fixed ve Decimal temel tipleri ve alt tipleri geçebilecektir. Gerçek sayı tipleri ondalıklı sayı literalleri olarak, aşağıdaki biçimlerde görüntülenirler:

Tamsayı_Kısmı . Ondalıklı_Kısım

veya

Tamsayı_Kısmı . Ondalıklı_Kısım E Üstel_Kısım

Bu alanlar arasında hiç boşluk bırakılmaz. Tamsayı kısmı ön boşluklar ve eksi işareti içerebilir. Ondalıklı kısım, sadece ondalık sayılarını ve belki de bunları izleyen sıfırları içerebilir. Üstel kısım, artı veya eksi işaretini ve sayıları belki de izleyen sıfırları içerebilir.

Float veri tipi için varsayılan olarak yukarıdaki değerler tanımlanmıştır. Diğer gerçek sayı tiplerinin alt paketlerinde de uygun varsayılan değerler tanımlanmıştır.

Ada.Text_IO.Float_IO generik bir pakettir ve bu paketin Float veri tipi spesifik güncel bir örneğinin yaratılarak programlarda kullanılır hale getirilmesi gerekir. Öntanımlı Float tipi için, Ada_Text_IO paketinde,

Ada.Float_Text_IO renames Ada_Text_IO.Float_IO(Float)

tanımı yapılarak, Ada.Float.Text_IO paketi Float öntanımlı veri tipi için kullanıcılara açılmştır. Kullanıcılar, Float tipi için kendileri spesifik generik paket örneklemesi yapmak zorunda değildir. Doğrudan, with Ada.Float.Text_IO; bildirimi ile öntanımlı veri Float veri tipi için öntanımlı olacak şekilde örneklenmiş spesifik paketi kullanabilirler. Fakat, öntanımlı Float veri tipinin, kullanıcı tarafından tanımlanmış alt tipleri için bu geçerli değildir. Kullanıcılar, kendi tanımladıkları alt veri tipleri için öntanımlı generik paketlerin spesifik güncel örneklerini programlarının tanıtım kısmında yaratmaları gerekmektedir.

Ada.Float_Text_IO Öntanımlı Spesifik Paketinde Standart Ortamdan Giriş/ Çıkış Prosedürleri

Aşağıdaki prosedürler tanımlanmıştır:

      procedure  Get(Item  : out Num;
                     Width : in  Field := 0);

Bu prosedür generik Num değişkenin yerini alacak tüm progenitor gerçek sayı tipleri ile çalışır. Burada Width parametresinin Field tipinden varsayılan değeri olan 0 değeri, tüm baştaki boşluk karakterlerini, sayfa ve satır sonlandırıcılarını atlar ve veriyi okunabilir en uzun şekli ile okuyarak geri döndürür. En uzun okunabilir biçim, aşağıdaki gibi olabilir :

Eğer Width parametresine 0 dan başka bir değer verilirse, baştaki boşluk karakterleri dahil tam verilen değer kadar karakter okumaya çalışır. Veri içinde pek bulunmasının olasılığı olmamasına rağmen, yine de bir satır sonlandırıcısı bulunursa, satır sonlandırıcısının okunması gereken bir karakterden önce gelmesi durumunda okumaya son verilir.

Get prosedürü, num yerine geçen öntanımlı gerçek sayı tipini giriş aşamasındaki okumaya göre geri döndürür. ve eğer Num bir gerçek sayı tipi ise ve Num'Signed_Zeros true ise, 0 değeri için verinin orijinal işareti korunur veya işareti yoksa 0 ın işareti pozitif olarak kabul edilir.

      procedure Put(Item : in Num;
                    Fore : in Field := Default_Fore;
                    Aft  : in Field := Default_Aft;
                    Exp  : in Field := Default_Exp);

Bu prosedür, Item parametresini bir ondalıklı literal (10 temelli Sayı) (desimal) olarak, Fore, Aft ve Exp parametrelerinin tanımlandığı biçimlendirme ile döndürür. Eğer değer negatif ise veya Num generik veri tipininyerine geçen gerçek sayı veri tipinde Num'Signed_Zeros True ve değer işaretli sıfır ise, tamsayı kısmına - işareti eklenir. Eğer Exp formal parametresinin değeri 0 ise, geri döndürülecek eğer Item formal parametresinin tamsayı kısmı, bu kısmı belirtecek kadar yeterli karakterden oluşur veya tamsayı kısmı yoksa, 0 değeri konulur.

Eğer Exp formal parametresi sıfırdan büyük bir sayı ise, tammsayı kısmı tek bir karakterden oluşur, Eğer Item formal parametresinin değeri 0 ise, 0.0 döndürülür.

Her iki durumda da, eğer tamsayı kısmı eksi işareti dahil, Fore formal parametresinin değerinden daha az karakter içeriyorsa, başa gerektiği kadar boşluk eklenerek eksiklik tamamlanır. Ondalık kısmının karakter sayısı, Aft formal parametresinin değeri ile belirlenir. Eğer Aft değeri 0 ise, ondalık kısmı tek bir karakterden oluşur. Geri döndürülen değer yuvarlatılmıştır. Son rakkam, eğer yarım ise sıfırdan uzağa yuvarlatılmıştır.

Eğer Exp formal parametresi sıfır ise, üstel kısım yoktur. Eğer Item formal parametresinin değeri 0.0 ise üstel kısım değeri sıfırdır. Eğer Exp formal parametresi sıfırdan büyük bir değer ise, üstel kısım, değeri belirtmek için gerektiği kadar karakter içerir. Bu durumda tamsayı kısmı tek bir karakterden ve gerekirse + veya - işasretinden oluşur. Eğer değerin üstel karakter sayısı değerin işareti dahil, Exp formal parametresi değerinden az ise, aradaki farkın kapatılması için gerektiği kadar boşluk karakteri üstel kısmın başına eklenir.

      procedure  Get(From : in String;
                     Item : out Num;
                     Last : out Positive);

Bu prosedür, verilen karakter dizisinin başından itibaren verileri karakter karakter okur. Okuma şekli aynen biir Get prosedürünün bir dosyadan okuduğu gibidir, sadece karakter dizisinin sonu satır sonlandırıcısı gibi etki eder. Okunan Num değerini Item formal parametresinin değeri olarak döndürür. Last formal parametresinin değeri, okunan karakter dizisinin son karakterinin From(Last) şeklinde indeks değeridir.

Eğer giriş akımı istenilen sözdizimini sağlamaz veya elde edilen değer Num tipinin bir alt tipi değilse, Exception_Data_Error hatası yayınlanır.

      procedure Put(To   : out String;
                    Item : in Num;
                    Aft  : in  Field := Default_Aft;
                    Exp  : in  Field := Default_Exp);

Item parametresinin değerini verilmiş olan karakter dizisine aktarır. İşlem aynı bir dosyaya çıkış gibidir. Fore parametresinin değeri baştaki boşluklar dahil tüm karakterleri verilen karakter dizisine yerleştirmek için yeterli olmalıdır.

Basit bir uygulama ile prosedürlerin çalışmasını izleyelim :

with Ada.Text_IO;
with Ada.Float_Text_IO;
procedure e3_s3_uyg_1 is
Bölünen , Bölen, Sonuç : Float;
begin
Bölünen := 2.0;
Bölen := 7.0;
Sonuç := Bölünen / Bölen;
Ada.Float_Text_IO.Put(Item => Sonuç);
Ada.Text_IO.New_Lİne;
Ada.Float_Text_IO.Put(Item => Sonuç , Fore => 1 , Aft => 16 , Exp => 0);
Ada.Text_IO.New_Lİne;
Ada.Float_Text_IO.Put(Item => Sonuç , Fore => 1 , Aft => 18 , Exp => 0);
Ada.Text_IO.New_Lİne;
Ada.Float_Text_IO.Put(Item => Sonuç , Fore => 1 , Aft => 50 , Exp => 0);
end e3_s3_uyg_1;
		

Bu Uygulamanın Sonuçları

2.85714285714286E-01

0.2857142857142857

0.285714285714285698

0.28571428571428569800000000000000000000000000000000

Problemin verisi olan 2/7 nin sonucu rasyonel siklik bir sayıdır ve 0.285 den sonra 714285 grubunun sonsuz sayıda tekrarı yapılmaktadır. Mathematica 7.01 bu bölmenin sonucunu 50 haneye kadar hesaplamış ve aşağıdaki sonucu bulmuştur.

0.28571428571428571428571428571428571428571428571429

Sonuçlardan görüldüğü gibi, görüntülenen değerlerin son sayıları yuvarlatılmış sayılardır. Float varsayılan veri tipinin varsayılan ondalık sayısı (requested precision) 6 ondalık olarak öntanımlanmıştır. 32 bitlik sistemler için tasarlanmış olan Long_Float öntanımlı veri tipi ise 11 ondalık duyarlıkta tanımlanmıştır. Günümüzde, hemen hemen tüm sistemler, 32 bitlik sistemlerdir ve hatta 64 bitlik Windows 7 sürümleri geniş ölçüde kullanılmaktadır. Bu nedenle, 16 bitlik sistemler için tasarlanmış olan Float veri tipinin, gerek 6 olan öntanımlı duyarlığı, gerekse çalışılan sisteme bağlı olarak, -3.40282E+38..3.40282E+38 arasındaki güvenli kapsam aralığı günümüz sistemleri için kesinlikle kapasite altı bir tanım olmak niteliğindedir. Buna rağmen bu mütevazi değerlerin bir dezavantaj değil, bir avantaj olarak düşünülmesi daha doğrudur. Çünkü, bu değerler günümüzde neredyse tüm sistemler tarafından desteklenmekte ve Float veri tipinin kullanıldığı tüm programların taşınabilirlik özelliğini arttırmaktadır.

Öntanımlı Float veri tipininn öntanımlı duyarlığı 6 dır ve bu duyarlığa kadar tüm verileri doğrulukla (Accuracy) değerlendirebilmektedir. Bu nedenle verilerin giriş/ çıkış işlemlerinde, Float veri tipi için 6 dan fazla duyarlıkta çıktılar istenmemelidir. Float veri tipinin 6 dan fazla ondalık sayının vereceği ek duyarlığın yanıltıcı olacağı, 6 ondalıktan sonraki ondalıkların güvenli olmayacağı her zaman gözönüne alınmalıdır. Yukarıdaki uygulamada 15 ondalığa kadar doğru değerler elde edildiği görülmesine rağmen bu konuda öntanımlı duyarlık değeri olan 6 ondalık aşılmamalıdır.

Long_Float veri itipi, 32 bit işletim sistemlerinin destekleyebileceği, öntanımlı 11 ondalık duyarlıkta tanımlanmıştır. Güveli kapsam aralığı da Float veri tipine kıyasla çok daha geniştir. Fakat, Long_Float veri tipi, geçmişten gelen bir tanımdır ve günümüzde sadece geçmişe uyum adına desteklenmektedir. İleride bu tanımın spesifikasyondan çıkarılacağı kesindir. Daha fazla duyarlık ve kapsam aralığı gerektiren hesaplar için, Long_Float yerine, duyarlık ve kapsam aralıkları gereksinmelere göre düzenlenmiş alt gerçek sayı tiplerinin özgün olarak tanıtılarak kullanılması daha doğrudur. Ayrıca, programların taşınabilirliği açısından özgün tiplerin kullanımları sağlık verilmektedir.

Long_Float veri tipinin bir uygulaması aşağıda görülmektedir:

with Ada.Text_IO;
with Ada.Long_Float_Text_IO;
procedure e3_s3_uyg_2 is
Bölünen , Bölen, Sonuç : Long_Float;
begin
Bölünen := 2.0;
Bölen := 7.0;
Sonuç := Bölünen / Bölen;
Ada.Long_Float_Text_IO.Put(Item => Sonuç);
Ada.Text_IO.New_Lİne;
Ada.Long_Float_Text_IO.Put(Item => Sonuç , Fore => 1 , Aft => 16 , Exp => 0);
Ada.Text_IO.New_Lİne;
Ada.Long_Float_Text_IO.Put(Item => Sonuç , Fore => 1 , Aft => 18 , Exp => 0);
Ada.Text_IO.New_Lİne;
Ada.Long_Float_Text_IO.Put(Item => Sonuç , Fore => 1 , Aft => 50 , Exp => 0);
end e3_s3_uyg_2;
		

Bu Uygulamanın Sonuçları

2.85714285714286E-01

0.2857142857142857

0.285714285714285698

0.28571428571428569800000000000000000000000000000000

Bu sonuçlardan 32 bit lik sistemler için Float ve Long_Float arasında bir fark kalmamış olduğu gibi bir sonuç çıkarılabilir. Yine de Long_Float veri tipinin öntanımlı duyarlığının 11 ondalık olduğu ve bu duyarlık sınırına kadar verilerin doğru okunacağı gözönüne alınmalıdır. Buna rağmen, eski bir teknoloji olan Long_Float tipi yerine, özgün olarak tasarımı yapılmış alt tiplerin tanımlanarak uygulanması hem programların gelecekte desteklenmesi, hem de taşınabilirlikleri açısından daha doğru olacaktır.

Valid XHTML 1.1