16 Mart 2011 Çarşamba

İlkel Türler-Tamsayılar

Bilgisayar programları, gerçek dünyada ve zihinlerimizde hali hazırda var olan süreçleri benzetmek (simüle etmek) amacıyla yazılır. Bu, kimi zaman verilen bir sayının çift olup olmadığını bulan bir hesaplama kadar basit olabilirken, kimi zamansa Mars gezegenine gönderilen bir aracın (Mars Rover) gezegen yüzeyinde güvenli bir biçimde dolaşmasını sağlayan yazılım kadar karmaşık olabilir. Ancak, üretilmesi istenen yazılım ne kadar karmaşık olursa olsun, iş eninde sonunda benzetilen süreçteki varlıkların özelliklerini temsil eden—ve genelde bilgisayar donanımları tarafından da bilinip makine kodları yoluyla doğrudan işlenebilen—basit türden değerlerin işlenmesi yoluyla icra edilir.  Örneğin, öğrenci kayıtlarını işleyen bir yazılımda gerçek iş, öğrencinin no, ad, ortalama gibi basit değerli özelliklerinin işlenmesiyle yapılır. İşte bu yazımızda, bilgisayar donanımı tarafından doğrudan desteklenmesi nedeniyle ilkel veri türü (kısaca, ilkel tür) olarak sınıflandırılan bu basit değerlerin ait oldukları türlerin tamsayıları temsil etmekte kullanılanlarına bakacağız.

Öncelikle, son tümcenin programlamaya yeni başlayanlarınızı şaşırtabilecek çoğul olma özelliğine dikkatinizi çekerim. Matematikte ℤ = {..., -2, -1, 0, 1, 2, ...} şeklinde tanımlanan ve sayma sayıları olarak adlandırılan tek bir tür varken, Java'da belirli sınırlar içindeki tamsayıları temsil eden dört türden bahsedebiliriz: byte, short, int ve long.1 Söz konusu türlerin belirli sınırlar içinde olmasının sebebi bilgisayarın sonlu bir belleğe sahip olmasında yatar: türleri ne kadar büyütmek istersek isteyelim, bilgisayar belleği pratik bir sınır olarak karşımıza çıkacaktır. Dört değişik tamsayı türünün bulunmasının nedeni ise, ortaya çıkan farklı gereksinimler sonucunda belleği ekonomik kullanma seçeneğini programcıya sunmak isteğidir.

Java tarafından desteklenen tamsayı türlerinin bellekte kapladığı alan ve bu türlere sahip terimlerin alabileceği değerlerin alt ve üst sınırları aşağıda verilmiştir. Buna göre, öğrenci notlarını tutmakta kullanılacak bir tamsayı dizisinin elemanlarının int yerine byte seçilmesi yerden %75'lik bir tasarruf anlamına gelecektir.

Tamsayı türleri ve sınır değerler2
Tür adıAlan (ikil)En küçükEn büyük
byte8-128127
short16-3276832767
int32-21474836482147483647
long64-9223372036854775808L9223372036854775807L

Tamsayı türlü ifadelerin işlenmesi sırasında, sınır dışına taşabilecek işlem sonuçlarının sessizce göz ardı edildiği ve elde edilen sonuçların aşağıda int türü için verilmiş olan öncelik-sonralık ilişkisine göre dönüştürüleceği unutulmamalıdır. [Integer.MAX_VALUE, herhangi bir int türlü ifadenin alabileceği en büyük değeri gösterirken, Integer.MIN_VALUE aynı ifadenin sahip olabileceği en küçük değeri temsil eder. Diğer türler için benzer işlev gören simgesel sabitlerin adları, Integer yerine Byte, Short veya Long konularak elde edilebilir.]


Dolayısıyla, aşağıdaki program s: -32767 b: 124 şeklinde bir çıktı üretecektir. Çünkü, s'nin yeni değeri 32767'den iki sonra gelen 32769 değil, yukarıdaki şeklin short türüne adapte edilmiş uyarlamasının gerektirdiği gibi -32767 olacaktır. Benzer şekilde, -127 değerine sahip b değişkeninden 5 çıkarılması sonrasında bu değişkenin yeni değeri 124 olacaktır, -132 değil.

TamsayıSınırları.java
public class TamsayıSınırları {
  public static void main(String[] ksa) {
    short s = 0x7ffF; // short s = 32767;
    s = (short) (s + 2);
    byte b = -0177; // byte b = -127;
    b = (byte) (b - 5);
    System.out.println("s: " + s + " b: " + b);
  } // void main(String[]) sonu
} // TamsayıSınırları sınıfının sonu

Örnek programımızın 4. ve 6. satırlarındaki biçimlendirmeler dikkatinizi çekmiştir. Zorunlu olarak yapılan bu işlemlerin sebebi, 2 ve 5 gibi tamsayı sabitlerinin değerleri ne kadar küçük olursa olsun int türlü kabul edilmeleridir. Bunun bir sonucu olarak, söz konusu satırların  biçimlendirmeler olmaksızın yazılması, bir short/byte ile bir int değerin toplanması/çıkarılması işleminin short/byte türü sınırları dışında olması olasılığı nedeniyle derleyici tarafından reddedilecektir. Çünkü, elde edilecek int türündeki değerin atama sonucunda daha küçük türden bir değişkenin yeni değeri olması olası bir değer kaybına işaret eder. Derleyici engeli, programcının bilinçli olarak bu işleme izin verdiğini belirten biçimlendirme ile aşılabilir.

Program metninin 3. ve 5. satırlarından da görülebileceği gibi, tamsayı sabitleri ondalık sistem dışında bir gösterim ile de yazılabilir; istenecek olursa, sayıların yazımında 8'li ve 16'lı taban da kullanılabilir.3 Bu takdirde, 0 ve 0x öneki ile başlayan sayıların yazımında kullanılabilecek simgelerin, sırasıyla, [0..7] ve [0..9, A..F, a..f] içinden seçilebileceği unutulmamalıdır.

Değineceğimiz son nokta, int sınırları dışındaki bir tamsayı sabitinin program metnine yazımı için kullanılması gereken gösterim. Küçük mutlak değerli tamsayılara da uygulanabilecek bu gösterim sayesinde, herhangi bir sabitin long türlü ele alınması sağlanabilir. Yapılması gereken tek şey, söz konusu sabitin sonuna L (veya l) eklemektir. Dikkat edildiğinde, aynı işin biçimlendirme ile, aşağıdaki kod parçasının ikinci satırında olduğu gibi, yapılmasının olanaksızlığı görülür. Zira, biçimlendirilme işlemi tamsayı sabitinin öncelikle int büyüklüğündeki bir bellek bölgesine konulmasını gerektirir ki, bu biçimlendirme öncesinde değer kaybının zaten yaşanmış olacağı anlamını taşır.
long l = 123456789098765L;
long l2 = (long) 123456789098765; // Derleme hatası!

  1. Karakterler bahsinde, char türünün de tamsayıları temsil etmek için kullanılabileceğini göreceğiz.
  2. Java 7 ile birlikte, sayıların algılanmasını kolaylaştırmak amacıyla alt çizgi (_)  kullanılarak rakamların gruplanması mümkün olacaktır. Örneğin, 123456789 yerine 123_456_789 yazılabilecektir.
  3. Java 7 ile birlikte, tamsayı sabitlerinin 0b öneki belirtilerek 2'li tabanda yazılması mümkün olacaktır.