Ada Programlama Dili Temelleri

Bölüm 3

Standard Pakette Tanımlanan Öntanımlı Veri Tipleri

Öntanımlı Gerçek Sayı Veri Tipleri

Bölüm 3 Sayfa 8

3.3.7 - Sabit Ondalıklı (Fixed Point) Tipler

Ada veri sistemi, iki türlü gerçek sayı (Real) veri tipi tanımlar, Bunlar Float ve Fixed gerçek sayı veri tipleridir. Float veri tipi hakkında Standard Pakette geniş bir tanım olmasına karşın, sabit ondalıklı tipler hakkında aşağıda görülen çok kısa bir bilgi bulunmaktadır.

-- The type universal_fixed is predefined.
-- The only multiplying operators defined between
-- fixed point types are
function "*" (Left : universal_fixed; Right : universal_fixed)
return universal_fixed;
function "/" (Left : universal_fixed; Right : universal_fixed)
return universal_fixed;

type Duration is delta implementation-defined range implementation-defined;
-- The predefined operators for the type Duration are the same as for
-- any fixed point type.

Bu bilgilerden sabit ondalıklı gerçek sayı tipleri için, Standard pakette fazla bir tanım yapılmadığı görülmektedir. Aslında buna gerek de yoktur. Gerek sabit ondalıklı tipler, gerekse Float veri tipi aynı gerçek sayı (Real)ailesinden veri tipleridir. Float tipi için tanımlanan işlemciler aynen sabit ondalıklı (Fixed) tipler için de geçerlidir.

Standart paketteki tanımdan, sabit ondalıklı gerçek sayı veri tipi için sacede Duration adlı bir öntanımlı veri tipi tanımlandığı görülmektedir. Bu veri tipi aslında tüm sayısal çalışmalar için kullanılabilir, fakat bir konvansiyon olarak sadece geçen süre ile ilgili çalışmalarda uygulanmaktadır. Bu nedenle, kullanıcılar, kendi gereksinmeleri için, gerekli sabit ondalıklı sayı veri tiplerini kendileri yaratıp uygulamak zorundadır. Bunun çok kolaylıkla gerçekleştirilebileceğini kendimiz uygulayarak göreceğiz.

Ada veri sistemi iki türlü sabit ondalıklı gerçek sayı veri tipi tanımlamaktadır. Bunlar, adi sabit ondalıklı gerçek sayı veri tipi ve desimal sabit ondalıklı veri tipidir.

Sabit Ondalıklı veri tiplerinin tanıtımları:

fixed_point_definition ::= ordinary_fixed_point_definition | decimal_fixed_point_definition

ordinary_fixed_point_definition ::= delta static expression real_range_specification

decimal_fixed_point_definition ::= delta static expression digits static expression [real_range_specification]

digits_constraint ::= digits static expression [range_constraint]

şeklinde gerçekleştirilir.

Sabit ondalıklı tipler, delta adı verilen bir eşiğin katları olarak düzenlenmiş veri tipleridir. Float tipi ile sabit ondalıklı tipler aralarındaki fark ilkinin göreli, ikincisinin mutlak doğruluk (accuracy) taşımasıdır. Hatırlandığı gibi, Float veri tipinde, eşik değişken, bağıl hata yaklaşık sabit iken, sabit ondalıklı tiplerde, esşik sabit, bağıl hata değişkendir. Sabit ondalıklı tiplerde bağıl hata küçük sayılarda yüksek, büyük sayılarda düşüktür ve bu yüzden sabit ondalıklı sayılar ile matematik ifadelerin hesaplanması avantajlı bulunmamamaktadır.

Sabit ondalıklı tip (ordinary fixed point) tipinde delta saklı sözcüğü ile belirlenen bir doğruluk sayısı (eşik) ve range saklı sözcüğü ile belirlenen tanım aralığı bulunur. Burada delta her gerçek sayı tipi değer olabilir.

Decimal tip olarak adlandırılan ikinci tipin doğruluk belirleyicisi, digits saklı sözcüğü ile belirlenen ondalık sayısıdır. Burada digits saklı sözcüğünün değeri bir tamsayıdır. Adi sabit ondalıklı tiplerde range belirlemesi zorunlu iken, desimal tipler için isteğe bağlıdır.

Tüm sabit ondalıklı tipler, small adı verilen bir sayının tamsayı katlarıdır. Bu değer, normal sabit ondalıklı tipler için, tipin delta değerinden büyük olamaz. Desimal tipler için ise, delta değerine eşittir. Eğer başkaca bir değer belirtilmemişse, normal sabit ondalıklı tipler için small değeri 2 nin delta değerinden az veya ona eşit üsleridir. Desimal tiplerin small değerleri 10 nun üsleri olarak tanımlanmıştır. Eğer bir range değeri belirlenecekse, bu aralığın her iki ucu,

–(10**D–1)*delta .. +(10**D–1)*delta

bağıntısını doğrulayan değerler arasında olmalıdır. Burada D belirtilen digits sayısı veya bu sayıyı veren statik ifadenin sonucudur. Tanımlanan bir desimal tipi, donanım desteklemezse, tanım geçerli kabul edilmez. Sabit ondalıklı sayıların tanıtımında tutulalabilecek en sağlıklı yol, gerekli değerlerin denenerek donanımın destekleyebildiklerinin uygulanması şeklinde olabilir.

Normal sabit ondalıklı tipler, aritmetik işlemler için çok avantajlı değildir. Bu yüzden kayan noktalı, aritmetiği destekleyen donanımlarda Float tipi tercih edilir. Günümüzde normalde tüm donanımlar kayan noktalı aritmetiği destekleyebildikleri için, normal sabit ondalıklı tipler, günümüzde ancak özel durumlarda uygulama alanı bulabilmektedir. Desimal tipler ise, muhasebe işlemleri için avantajlı olduklarından bu alanda geniş ölçüde uygulanmaktadır.

Öntanımlı tek sabit ondalıklı veri tipi Duration tipidir. Duration bir adi sabit ondalıklı tiptir ve gerek digits gerekse range değerleri yerleşime bağlı (Implementation Defined) olarak tanımlanmıştır. Duration veri tipinden nesneler, saat, tarih çalışmaları için yapılan uygulamalarda kullanılır. Ada 2012 spesifikasyonu, öntanımlı Duration adi sabit ondalıklı veri tipinin bir tam günü kapsayacak pozitif ve negatif en az 86400 saniyeyi kapsaması gerektiğini belirtmektedir. Duration'Small 20 milisaniyeden daha yüksek olmayacaktır. GNAT 2012 RM de Duration'Small değerinin 100 milisaniyenin üzerinde olmayacağı belirtilmiştir ve Duration'Small = 10**(-9)) olarak açıklanmıştır. Duration öntanımlı adi sabit ondalıklı veri tipinin çalıştığımız sistemdeki yerleşim değerleri biraz ileride sorgulanacaktır.

Adi sabit ondalıklı tiplerin konsol görüntülerinin sağlanabilmesi için, Ada_Text_IO öntanımlı paketinde, Ada.Text_IO.Fixed_IO alt paketinin örneklenmesi ile özgün bir giriş/çıkış paketi yaratılması gerekir.

Aynı şekilde, Decimal sabit ondalıklı tiplerin konsol görüntülerinin sağlanabilmesi için, Ada_Text_IO öntanımlı paketinde Ada.Decimal_IO adında öntanımlı bir alt paket sağlanmıştır. Kullanıcılar, bu paketin kendi veri tipleri için örneklenmesi ile özgün bir giriş çıkış paketi yaratabilirler.

3.3.7.1 - Universal_Fixed

Standart pakette tanımlanmış olan Universal_Fixed veri tipi tam olarak kuramsal bir tiptir ve kullanıcıların bu veri tipine erişimi yoktur.

3.3.7.2 - Adi Sabit Ondalıklı Tipler

Öntanımlı bir adi sabit ondalıklı tip yoktur. Kullanıcılar bu veri tipini kendi gereksinmelerine göre özgün olarak tanımlayıp uygulamaları gerekmektedir. Aşağıda görülen prosedürde, adi sabit ondalıklı bir veri tipi tanımlanmıştır.

with Ada.Text_IO;


procedure b3_3_7_2_uyg_1 is

   type Sabit_Ondalık is delta 2.0 range 0.00 .. 1000.00;
   
   package Sabit_Ondalık_IO is new Ada.Text_IO.Fixed_IO(num => Sabit_Ondalık);
   
   x : constant  Sabit_Ondalık  := 7.2;
   
   Veri : Sabit_Ondalık;

begin

   Ada.Text_IO.Put(Item => "Lütfen Verinizi Giriniz : ");
   
   Sabit_Ondalık_IO.Get(Item => Veri);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Girilen Veri : ");
   
   Sabit_Ondalık_IO.Put(Item => Veri);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Veri + 2.0 Değeri: ");

   Sabit_Ondalık_IO.Put(Item => veri + 2.0);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Sabit = 7.2 Değeri: ");

   Sabit_Ondalık_IO.Put(Item => x);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Sabit = 7.2 + 2.0 Değeri: ");

   Sabit_Ondalık_IO.Put(Item => x + 2.0);

end b3_3_7_2_uyg_1;

Bu programın sonucu,

Lütfen Verinizi Giriniz : 7.2

Girilen Veri :     8.0

Veri + 2.0 Değeri:     10.0

Sabit = 7.2 Değeri:     6.0

Sabit = 7.2 + 2.0 Değeri:     8.0

olmaktadır.
		

Yukarıdaki prosedürde, alınan sonuçlar, hiç hoş değildir ve bilgisayarlarla çalışılırken son derece dikkatli olunması için uyarı niteliğinde sayılmalıdır. Öncelikle, tanımlı olan Sabit_Ondalık adi sabit ondalıklı veri tipindeki değerler, 0.0 , 2.0 , 4.0 , 6.0 , 8.0 , 10.0 kümesi içinde olan sayılardır. Küme içindeki elemanlar, başlangıç : 0.0 , ilk eleman : 2.0 x 1 = 2.0, ikinci eleman : 2. 0 x 2 = 4.0, üçüncü eleman : 2.0 x 3 = 6.0, dördüncü eleman : 2.0 x 4 = 8.0, beşinci eleman : 2.0 x 5 = 8.0 ... şeklinde oluşmaktadır. Bu küme başka bir sayı içermemektedir ve eğer bir değer Sabit_Ondalık kümesi içinde tanımlı olacaksa, küme içindeki sayılardan birisine yuvarlatılması gerekecektir.

Yukarıdaki prosedürde, alınan sonuçlar, bu durumda, tanımlı Sabit_Ondalık kümesi içine yerleştirilme aşamasında, gerçek değer ve makine değeri arasında kaçınılmaz bir farklıılk yaşanmakta ve elimizdeki örnek gibi, gerçek değer ve yerleştirilecek değerler arasında dengenin iyi tutturulamamış olduğu sistemlerde, doğruluk (accuracy) kaybı ortaya çıkmaktadır. Bunun çaresi, gerçekleşek değerlere uygun olabilecek sabit ondalıklı sistemlerin oluşturulmasıdır.

Yine yukarıdaki prosedürde, alınan sonuçlar, sabit değerin (constant) ile verinin aynı değerde olmasına karşın farklı küme elemanlarına adapte edilmiş olmasıdır. Bu iki değerin, adapte edilmiş değerleri ile yapılan aritmetik toplama işlemi beklenenden çok farklı sonuç vermektedir. Bunun nedeni, sabit sayıların ve değişkenlerin makine sayıları oluşturulurken farklı algoritmalar kullanılmış olmasından kaynaklanabilir. Buradaki esas sorun, oluşturulmuş olan veri sisteminin eldeki verilere uygun olmamasıdır. Bu durum, aşağıda görülen prosedürde düzeltilmeye çalışılmıştır.

with Ada.Text_IO;


procedure b3_3_7_2_uyg_2 is

   type Sabit_Ondalık is delta 0.1 range 0.00 .. 1000.00;
   
   package Sabit_Ondalık_IO is new Ada.Text_IO.Fixed_IO(num => Sabit_Ondalık);
   
   x : constant  Sabit_Ondalık  := 7.2;
   
   Veri : Sabit_Ondalık;

begin

   Ada.Text_IO.Put(Item => "Lütfen Verinizi Giriniz : ");
   
   Sabit_Ondalık_IO.Get(Item => Veri);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Girilen Veri : ");
   
   Sabit_Ondalık_IO.Put(Item => Veri);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Veri + 2.0 Değeri: ");

   Sabit_Ondalık_IO.Put(Item => veri + 2.0);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Sabit = 7.2 Değeri: ");

   Sabit_Ondalık_IO.Put(Item => x);
   
   Ada.Text_IO.New_Line;
   
   Ada.Text_IO.Put(Item => "Sabit = 7.2 + 2.0 Değeri: ");

   Sabit_Ondalık_IO.Put(Item => x + 2.0);

end b3_3_7_2_uyg_2;

Bu programın sonucu,

Lütfen Verinizi Giriniz : 7.2

Girilen Veri :     7.2

Veri + 2.0 Değeri:     9.2

Sabit = 7.2 Değeri:     7.2

Sabit = 7.2 + 2.0 Değeri:     9.2

olmaktadır.
		

Yukarıdaki prosedürde, durumun düzeldiği açıkça görülmektedir. Burada, delta değeri 0.1 değerine indirilmiş, Oluşturulan değerler kümesindeki değerler ile, verilerin uyumu sağlanmıştır. Değerler kümesindeki verilere yakın elemanlar, 7.0 , 7.1 , 7.2 , 7.3 ... değerindedir ve verilerin değerler kümesine yerleştirilmesi sırasında bir doğruluk (accuracy) kaybı yaşanması olasığı kalmamıştır.

Sabit ondalıklı sayılar, small adı verilen ve delta değerinden küçük veya eşit olan bir sayının katları olarak oluşurlar. Serinin ilk ve son elemanları, serinin diğer elemanlarından sadece small değeri kadar az veya çok olabilirler. GNAT 2012 derleyicisinde small değeri 2+/- tamsayı şeklinde olabilir. Derleyici, forT'Small use 0.01 şeklinde 2nin üsleri yerine 10 temeline göre small düzenlenmesine zorlanabilrise de bu gibi, derleyicinin çalışmasını etkileyecek düşük düzeyli düzenlemelerin, ancak gerektiği zaman ve konuyu iyi bilen kullanıcılar tarafından yapılmasının daha uygun olacağı uyarısı yapılmaktadır. Çoğunlukla, konudan uzak kullanıcıların yapacakları alçak düzey düzenlemelerin yararsız ve yan etkilerinin iyi hesaplanamaması nedeni ile tehlikeli olabileceği de hatırda tutulmalıdır.

Günümüzde GNAT 2012 derleyicisinin normal olarak yerleşimi 32 bit lik sistemlerdedir. Bu sistemlerde small değerinin 10-10 kadar düşük değerlerle tanımı olasılığı bulunmaktadır. Burada unutulmaması gereken gerçek, small değerinin kapsam alanı ile antagonist olarak çalışmasıdır. Düşük small değerleri, dar bir kapsam alanına neden olacaktır. Bu nedenle, sonuçların hesaplanabileceği kapsam alanını elde etmek ve hesapların gerektirdiği duyarlığın sağlanması için bir optimizasyonun sağlanması gereklidir. Çalıştığımız,x86 işlemcisi üzerinde çalışan 64 bit Windows 7 sistemi üzerinde yerleşmiş GNAT 2012 derleyiciisinde ulaşabildiğimiz bazı ekstrem değerler aşağıda görülmektedir:

type  Sabit_Ondalık  is delta 1.0E-14 range -1.0E4 ..1.0E4;

type  Sabit_Ondalık  is delta 1.0E-13 range -1.0E5 ..1.0E5;
		
type  Sabit_Ondalık  is delta 1.0E-12 range -1.0E6 ..1.0E6;
		
type  Sabit_Ondalık  is delta 1.0E-11 range -1.0E7 ..1.0E7;
		 

Belitilmiş olduğu gibi, bunlar ekstrem değerlerdir ve gerçekte çok daha düşük duyarlıklar gerekli olmakta ve çok daha geniş kapsam alanları sağlanabilmektedir. Doğal olarak denemeler yapılması ile, sonuçlların yaklaşık değerleri bulunarak, daha dar kapsam alanları ve yüksek duyarlıklarla çalışma olanağı da olabilir.

Sabit ondalıklı veri sisteminin matematik ifadelerde az kullanıldığı gerçektir. Bunun nedeni, bu veri tipinin eksponent işlemcisi içermemesi yanında, Float sisteminin, hem kapsam hem de duyarlık açısından daha üstün olduğu için, matematik çalışmalarda sabit ondalıklı sistemin kullanımına gerek olmamasıdır.

Aşağıdaki ilk prosedürde bir algoritma, önce makinenin verebileceği en yüksek duyarlık ve kapsam alanını sağlayabilen Long_Long_Float veri tipi kullanılarak, ikinci prosedürde ise, aynı algoritma sabit ondalıkta ve sonucu içerebilecek en dar kapsam alanı ile en yüksek duyarlık içeren bir tip ile hesaplanmış ve sonuçlar karşılaştırılmıştır.

with Ada.Text_IO;
with Ada.Long_Long_Float_Text_IO;

procedure b3_3_7_2_uyg_3 is

   
   Veri : Long_Long_Float;

begin
   
   veri := ((16.9E-3 * 25.0)/ (1.0E-4 - 25.8 *3.0E5) *1.0E6 - 0.000016) * ( 1.05663 - 4.5E6);

   Ada.Text_IO.Put(Item => "Sonuç : ");

   Ada.Long_Long_Float_Text_IO.Put(Item => Veri , Fore => 0 , Aft => 4 , Exp => 0);
   

end b3_3_7_2_uyg_3;


Bu Prosedürün Sonucu, 

Sonuç : 245711.4772

olmuştur.
		
with Ada.Text_IO;

procedure b3_3_7_2_uyg_4 is

   type Sabit_Ondalık is delta 1.0E-12 range 1.0E4 ..1.0E6;
   
   package Sabit_Ondalık_IO is new Ada.Text_IO.Fixed_IO(num => Sabit_Ondalık);
   
   veri :Sabit_Ondalık;

begin
   
    veri := ((16.9E-3 * 25.0)/ (1.0E-4 - 25.8 *3.0E5) *1.0E6 - 0.000016) * ( 1.05663 - 4.5E6);

   Ada.Text_IO.Put(Item => "Sonuç : ");

   Sabit_Ondalık_IO.Put(Item => Veri , Fore => 0 , Aft => 4 , Exp => 0);
   
   
end b3_3_7_2_uyg_4;

Bu Prosedürün Sonucu,

Sonuç : 245709.1809

olmuştur.
		

İki prosedürün verdiği sonuçlar arasında farklılık olduğundan, aynı algoritma 17 ondalık ile Long_Long_Float veri tipine yakın işlem yapabilen MathCad 14 ile kontrol edilmiş ve ilk prosedür ile aynı sonuç bulunmuştur. Bu durumda, Sabit ondalıklı veri sistemi, Float sistemine göre, hem daha dar kapsam alanlı, hem daha küçük duyarlıklı olduğu, üstelik verdiği sonuçalrın hata paylarının daha büyük olduğu açıklıkla görülmüştür. İlk prosedürde, Long_Long_Float yerine Float dahi kullanılsa yine sabit ondalıklı sistemden daha iyi sonuç alınabilmektedir. Bu durumda, matematiksel ifadelerin hesaplanması için, sabit ondalıklı veri sisteminin kullanılması için bir neden olmadığı söylenebilir. Bu nedenle, matematiksel hesaplamalarda hemen daima Float sistemi kullanılır.

Sabit ondalıklı veri sistemi toplama çıkarma işlemlerinde daima doğru (yaklaşık olmayan) sonuçlar verdiği için, en çok muhasebe, stok kontrol gibi alanlarda kullanılır.

3.3.7.3 - Desimal Sabit Ondalıklı Tipler

Desimal sabit ondalıklı tipler aynı adi sabit ondalıklı tipler gibidir,sadece delta değerleri 2 değil 10 sayısının üslerine göre belirlenir.Ayrıca,desimal tiplerin tanımında duyarlılık ondalık sayısı olan digits de belirtilmelidir. Bu şekilde aynı zamanda tipin duyarlık ondalık sayısı da tanımla birlikte belirlenmiş olur. Tanımından da görülebileceği gibi, desimal tiplerin tanımında kapsam aralığının belirtilmesi isteğe bağlıdır ve çoğunlukla boş geçilir.

Desimal sabit ondalıklı tiplerin değerleri gerektiğinde daima sıfıra yakın olacak şekilde yuvarlatılır. Desimal sabit ondalıklı tipler, adi sabit ondalıklı tiplerde daha avantajlı olmalarına rağmen yine de matematiksel hesaplarda kullanımları yeterince avantajlı değildir. Bunun yerine, muhasebe istemlerinde, stok kontrol çalışmalarında, hastahane-eczane sitemlerinde, maaş bordroları, personel kayıtlarında, olağanüstü kullanışlı olurlar. Bu veri tiplerinin kullanımları için çeşitli öntanımlı programlar, Information Systems Annex de verilmiştir. Burada bu tiplerin sadece tanıtımları yapılacaktır.

Aşağıda görülen prosedürde, desimal bir tipin tanıtımı ve uygulanması yapılmıştır.

with Ada.Text_IO;
with Ada.Integer_Text_IO;

procedure b3_3_7_3_uyg_1 is

   type Desimal is delta 0.01 digits 14;
   
   package Desimal_IO is new Ada.Text_IO.Decimal_IO(num => Desimal);
   
   Saat_Ücreti :  constant Desimal := 30.86;
   
   Ödenecek_Ücret : Desimal;
   
   type Haftalık_Saat_Sayısı is range 0 .. 50 ;
   
   Çalışılan_Saat : Haftalık_Saat_Sayısı;

begin
   
   Ada.Text_IO.Put(Item => "Lütfen Haftalık Çalışılan Saati,  0 ile 50 Arası Bir Tamsayı Olarak Giriniz : ");
   
   Ada.Integer_Text_IO.Get(Item => Integer(Çalışılan_Saat));
   
   Ödenecek_Ücret := Integer(Çalışılan_Saat) * Saat_Ücreti;
   
   Ada.Text_IO.Set_Col(To => 20);
   
   Ada.Text_IO.Put("Haftalık Çalışılan Saat : ");
   
   Ada.Text_IO.Set_Col(To => 62);
   
   Ada.Integer_Text_IO.Put(Item => Integer(Çalışılan_Saat));
   
   Ada.Text_IO.Set_Col(To => 20);
   
   Ada.Text_IO.Put("Saat Ücreti (TL.Krş) : ");
   
   Ada.Text_IO.Set_Col(To => 67);
   
   Desimal_IO.Put(Item => Saat_Ücreti , Fore => 0 , Aft => 2 , Exp => 0);
   
   Ada.Text_IO.Set_Col(To => 20);
   
   Ada.Text_IO.Put("Ödenecek Ücret (TL.Krş) : ");
   
   Ada.Text_IO.Set_Col(To => 60);

   Desimal_IO.Put(Item => Ödenecek_Ücret , Fore => 0 , Aft => 2 , Exp => 0);
   
   
   
end b3_3_7_3_uyg_1;

Bu Prosedürün Sonucu :

Haftalık Çalışılan Saat :                            10
Saat Ücreti (TL.Krş) :                         30.86
Ödenecek Ücret (TL.Krş) :                308.60

olmaktadır.
		

Yukarıdaki prosedürde, açıklanacak birçok nokta bulunmaktadır. İlk olarak, prosedürde kullanıcı tanımlı özgün bir tip olan Haftalık_Saat_Sayısı veri tipi üzerinde durulacaktır. Kullanıcıya özel özgün tiplerin tanıtımı kısa süre sonra incelenecektir. Fakat, burada ilk bir tanıtım örneği verilmektedir. Haftalık_Saat_Sayısı bir tip değil bir alt tiptir, çünkü tipler isimsiz (anonim) alt tipler isimli olurlar. Her veri tipinin ilk alttipi kendisidir. Tipler kısıtsız (unconstrained) iken alt tipler daima kısıtlıdır. Haftalık_Saat_Sayısı, bir tamsayı tipinin isimli alt tipidir. Haftalık_Saat_Sayısı alt tipinin temel tipinin özelliklerine Haftalık_Saat_Sayısı'Base niteliği ile erişilebilir. Haftalık_Saat_Sayısı alt tipinin temel tipi, Haftalık_Saat_Sayısı'Base kapsam sınırı, donanımın 32 bit genişliğinde Tamsayı tiplerine verdiği, -231 (=-2147483648) .. 231-1 (= 2147483647) kapsamında olabilir. Haftalık_Saat_Sayısı alt tipinde ise sadece haftalık çalışma saati için gereksinme olacak kadar 0 ..50 (saat) kapsam aralığı verilmiştir. Bu şekilde, gereksinmelere uygun veri tipleri oluşturularak, veri yanlışlılklarından korunma sağlanması amaçlanmaktadır.

Haftalık_Saat_Sayısı veri tipi bir tamsayı veri tipidir fakat Integer veri tipi ile bir ilgisi yoktur. Bir Integer alt tipi olarak tanımlanmamıştır. Integer veri tipi için tanımlanmış kolaylıklardan yararlanamaz. Örnek olarak Ada.Integer_Text_IO öntanımlı paketinden yararlanılarak görüntülenemez. Fakat, bu bir tamsayı tipidir ve tamsayı tipleri ile uyumludur. Haftalık_Saat_Sayısı veri tipinden bir X nesnesi, Integer(X) şeklinde, Integer veri tipine dönüştürülebilir ve böylece Integer veri tipi için tanımlı kolaylıklardan yararlananabilme ayrıcalığı elde eder. Örnek olarak, Ada.Integer_Text_IO öntanımlı paketinden yararlanılarak görüntülenebilir.

Haftalık_Saat_Sayısı veri tipi aşağıdaki gibi, bir Integer veri tipi alt tipi olarak da tanımlanabilirdi :

subtype Haftalık_Saat_Sayısı is Integer range 0 ..50;
		

Bu şekilde yine 0 .. 50 arası tanımlı olur ve Integer veri tipi için öntanımlı kolaylıklardan yararlanabilirdi. Fakat bu şekilde yapılmamış ve ayrı bir özgün tamsayı tipi yaratma yoluna gidilmiştir. Bu durumda, nesnelerinin Integer veri tipi için öntanımlı kolaylıklardan yararlanabilmeleri için, açık (explicit) bir veri tipi dönüştürümesi ile Integer veri tipine dönüştürülmeleri gerekli olmuştur.

Haftalık_Saat_Sayısı veri tipi özgün ve bağımsız bir tamsayı veri olduğundan, görüntülenmesi için, Ada.Text_IO.Integer_IO alt paketinden (bk 2.17 yararlananarak aynen sayılabilir veri tipilerinde yaptığımız gibi,

package Saat_IOis new Ada.Text_IO.Integer_IO(num => Haftalik_Saat_Sayısı);
		

yeni bir giriş/çıkış paketi tanımlanarak, Haftalik_Saat_Sayısı nesnelerinin giriş/çıkışı sağlanabilirdi, fakat, böyle yeni bir özgün paket örneği yaratılmaktansa, Haftalik_Saat_Sayıs nesnelerini açık dönüştürme ile Integer veri tipine dönüştürülüp, giriş/çıkışlarının sağlanması yoluna gidilmiştir. Her iki yöntem de geçerlidir ve kullanıcının tercihine bağlıdır. Sonuçta amaç, Haftalik_Saat_Sayısı tipinde nesnelerin giriş/çıkışlarının sağlanabilmesidir.

Sabit ondalıklı tiplerin nesneleri, Integer tipleri ile çarpılıp bölünebilirler. Bu özellikleri, idari işlerde kullanılmalarının bir başka gerekçesidir. Fakat, Haftalık_Saat_Sayısı veri tipi nesneleri Integer veri tipinin veya Integer veri tipinin alt tiplerinin nesneleri değildir. Haftalik_Saat_Sayısı veri tipi, özgün ve bağımsız bir tamsayı veri tipidir. Integer veri tipi ile ilgisi yoktur ve Integer tipinde nesnelerin kullanılabildiği sabit ondalıklı sayıların çarpım veya bölüm işlemlerinde işlenen olarak kullanılamaz. Bunun için Haftalık_Saat_Sayısı veri tipindeki nesnelerin Integer veri tipi nesnelerine dönüştürülmeleri gereklidir ve yukarıdaki prosedürde de bu yöntem uygulanmıştır.

3.3.7.4 - Sabit Ondalıklı Veri Tiplerine Uygulanabilen Nitelikler

Sabit ondalıklı veri tipleri, gerçek sayı veri tipleridir. Bu veri tipleri, skaler, veri tipleridir. Ayrıca, bu veri tiplerinin ayrık ve sayılabilir karakterleri daha çok vurgulanmıştır. Bu nedenle, tüm skaler, sayılabilir ve ayrık verilere uygulanabilen nitelikler sabit ondalıklı verilere uygulanabildiği gibi, salt sabit ondalıklı verilere uygulanabilir nitelikler de bulunmaktadır. Bunlar sırası ile incelemeye çalışacağız.

İlk incelemeye çalışacağımız nitelik, S'Delta olacaktır. Bu nitelik, tanımlanmış olan sabit ondalıklı bir alt tip için, delta değerini universal_real tipinde döndürür. Bu niteliğin tanımı, aşağıda görülmektedir.

Aşağıda görülen prosedürde, S'Delta niteliğinin sorgulandığı bir uygulama görülmektedir.

with Ada.Text_IO;

with Ada.Float_Text_IO;

procedure b3_3_7_4_uyg_1 is

   type Desimal is delta 1.0E-2 digits 4 range -10.0 .. +10.0;
   
begin

   Ada.Text_IO.Put(Item => "delta değeri : ");

   
   Ada.Float_Text_IO.Put(Item => Desimal'Delta, Fore => 0 , Aft => 4 , Exp => 2);
   
   
end b3_3_7_4_uyg_1;

Bu Prosedürün Sonucu :

delta değeri : 1.0000E-2

olmaktadır.
		

Eğer bir alt tip delta değeri olmadan tanımlanmışsa, o alt tipin delta değeri, baz tipin delta değerine eşittir.

Bir sabait ondalıklı tipin digits değeri, S'Digits nitelik değeri ile sorgulanabilir. Bu nitelik aşağıda açıklanmıştır.

Aşağıda görülen prosedürde, bir desimal sabit ondalıklı veri tipinin S'Digits niteliği sorgulanmaktadır.

with Ada.Text_IO;

with Ada.Integer_Text_IO;

procedure b3_3_7_4_uyg_2 is

   type Desimal is delta 1.0E-2 digits 4 range -10.0 .. +10.0;
   
begin

   Ada.Text_IO.Put(Item => "digits değeri : ");

   
   Ada.Integer_Text_IO.Put(Item => Desimal'Digits);
   
   
end b3_3_7_4_uyg_2;

Bu Prosedürün Sonucu :

digits değeri :           4

olmaktadır.

S'Digits niteliğinin tanımı, bir sabit ondalıklı tiipin, özellikle, digits kısıtı açıkça belirli olan bir desimal sabit ondalıklı tipinin kapsam aralığı genişliğinin tipin delta ve digits değerleri ile, ters orantılı olduğunu belirtmektedir. Yani özellikle bir desimal sabit ondalıklı tipin delta ve digits değerleri tanımlanmdığında, bu tipin kapsam baz kapsam aralığı oluşmakta ve tipin tanımındaki kapsam aralığı bu baz tipin kapsam aralığı içinde kalmazsa tipin tanımı kabul edilmemektedir. Diğer bir söylem şekli ile, kullanıcı delta ve digits değerlerini belirlediğinde, tipin temel kapsam alanı bu iki tanıma bağlı olarak sistem tarafından oluşturulmakta ve kullanıcının yapmış olduğu kapsam aralığı tanımının, bu temel tanımla uyuşup uyuşmadığı kontrol edilmektedir.

Desimal sabit ondalıklı tiplerde, small değeri, tipin belirtilen delta değerine eşittir. Adi sabit ondalıklı ondalıklı veri tiplerinde ise, bu değer açık değildir, fakat yine de belirtilmiş olan delta değerine yakın olması gerekir. Adi sabit ondalıklı veri tipleri için, bu değer, ileride göreceğimiz, nitelik değerlerinin kullanıcı tarafından belirtilmesi yöntemine göre, kullanıcı tarafından belirtilebilir. Aşağıda tanımı verilen S'Small niteliği, özellikle baz alt tip olarak tanımlanmış olan (her tipin ilk alt tipi kendisidir) adi sabit ondalıklı tiplerde uygulanmış olan small değerlerinin açıklanmasında yararlı olmaktadır. Bu niteliğin tanımı aşağıda verilmiştir.

Aşağıda görülen prosedürde, S'Small niteliğinin sorgulandığı bir uygulama görülmektedir.

with Ada.Text_IO;

with Ada.Float_Text_IO;

procedure b3_3_7_4_uyg_3 is

   type pH is delta 1.0E-2 range 0.00 .. 14.0;
   
begin

   Ada.Text_IO.Put(Item => "small değeri : ");

   
   Ada.Float_Text_IO.Put(Item => pH'Small, Fore => 0 , Aft => 4 , Exp => 2);
   
   
   
end b3_3_7_4_uyg_3;

Bu Prosedürün Sonucu :

small değeri : 7.8125E-3

olmaktadır.
		

Yukarıdaki prosedürün, sonuçlarından da görüldüğü gibi, bir adi sabit ondalıklı temel alt tip (pH veri tipi ismli bir temel, yani bir başka temel tipin temel alınmadığı bir alt tip olarak kabul edilir. Temel tip olan pH'Base ismsiz -anonim- ve kapsam alanı sınırsızdır) için, gerçekleşmiş olan small değeri, delta değerine yakındır.

On temelli sayılar ile çalıştığımızdan, desimal sabit ondalıklı tiplerin digits değeri ile çakışık olan on temelli small değerlerinin izlenmesi, bizim için daha kolay olmaktadır.

devam =>