Ana Sayfa

Bilgisayar Eğitim CD

Bilgisayar Kitapları

 
 
Adım Adım Web Eğitim Seti Adobe Flash Eğitim Seti


C# Tamsayılar

Tamsayılar

Tamsayılar (integer ya da int), bütün programlama dillerinde bulunurlar. Tamsayıların çeşitlerini, gücünü ve sınırlarını bilmekte yarar var. C#'ta nasıl tanımlandığını ve kullanıldığını aşağıdaki örnekte inceleyelim.

1

using System;

2

class Program

3

{

4

static void Main()

5

{

6

int i1 = 10;

7

int i2 = 20;

8

int i3 = i1 + i2;

9

Console.WriteLine(i3);

10

}

11

}

Günümüz sayısal bilgisayarları, ikili sayı sistemi ile çalışır ve her bilgi 0 ve 1 rakamlarından oluşan veri bitlerine dönüştürülür. İkili sayı sisteminde her bir rakama bit denir. 1 bitlik bir veri ya 0 ya da 1 olur, yani 2 değişik durum oluşabilir. 2 bitlik bir sayı ise, 00, 01, 10 ya da 11 olabilir, yani 4 farklı durum oluşabilir. Bunu basitçe hesaplamak istersek, 2^bitsayısı şeklinde formüle edebiliriz. Mesela 32 bitlik bir veri 2^32 farklı durumda (4.294.967.296 çeşit) olabilir.

C#, int türünde bir değişken için 32 bit (4 byte) kullanır. int, hem pozitif hem de negatif sayıları tutabilir. Bu yüzden 32 bitlik işaretli tamsayı da denir. İşaretli denmesinin sebebi, hem negatif hem de pozitif sayıları tutabilmesidir. Bunu da, en soldaki bir biti işaret için kullanarak yapar. int tipinde bir tamsayıyı ikili sistemdeki karşılığı ile yazarsak, solundaki bit 0 ise, sayı pozitif, 1 ise negatiftir. Eğer 32 bitin tamamı 0 ise sayı 0 olur. int türünde, bir sayı yazmak istersek, -2.147.483.648 ile 2.147.483.647 arasında bir sayı yazabiliriz.

checked – unchecked durumları

Belirtilen sınırların dışında bir sayıyı int türünde bir değişkende tutmak istersek taşma meydana gelir. Eğer -2.147.483.648 sayısından daha küçük bir sayı tutmak istersek underflow, 2.147.483.647 sayısından büyük bir sayı tutmak istersek overflow durumu oluşur. Biz genel olarak her iki durumu da overflow olarak adlandırırız.

Bunu engellemek mümkündür. Eğer program yazmak için key of csharp kullanıyorsak, bunu aşağıdaki resimde görüldüğü gibi compile options menüsünden yapabilirsiniz.

checked – unchecked durumları

Eğer resimde gördüğünüz Check For Arithmetic Overflow seçeneği işaretli değilse, oluşacak taşmaları dikkate almadan işlemler yapılacaktır ve sonuçların yanlış çıkma ihtimali yükselecektir. Eğer, resimde görülen seçenek işaretli olursa, taşmalar dikkate alınacak ve çalışma sırasında taşma hataları görülecektir.

Check For Arithmetic Overflow

Belirli bir program bloğunun, aritmetik işlem taşmalarından muaf tutulmasını sağlayabiliriz ya da tam tersi olarak, taşma işlemlerinde hata oluşturacak şekilde işaretleyebiliriz. Bu işi de checked ya da unchecked program blokları oluşturarak yaparız.

Mesela programımız derleme sırasında aritmetik taşma işlemlerini denetleme seçeneği aktifken derlenmiş olsun. Bu durumda programı çalıştırdığımızda aritmetik taşma işlemi olunca program kesilecektir. Bir program bloğunu seçelim ve checked bloğu yapalım. Taşma durumu oluştuğunda checked bloğunun içerisindeki kodlarda oluşan taşmalar dikkate alınmaz. Derleme sırasında aritmetik taşma işlemlerini denetle seçeneği aktif değilken ise unchecked bloğu için tam tersi mümkün oluyor.

Aşağıdaki örneği aritmetik taşma işlemlerinde taşma hatası verecek şekilde ayarlanmış olarak derlerseniz taşma durumu oluşmayacaktır ve sonuç ekrana yazdırılacaktır. Bunu sağlayan ise unchecked bloğudur.

1

using System;

2

class Program

3

{

4

static void Main()

5

{

6

unchecked

7

{

8

int A = 1000000000;

9

int B = A * 20;

10

Console.WriteLine(B);

11

}

12

}

13

}

Buraya kadar olan kısımda tamsayı türü olarak sadece int bahsedildi ama, tamsayılar sadece 32 bitlik işaretli tamsayılar değildir. Ama int C#’ta en çok kullanılan tamsayı türüdür. Mesela bir etkinliğe katılan insan sayısını tutacaksanız, bunu negatif sayılara da izin veren int türü ile yapmak zorunda değilsiniz. İşaretsiz 32 bit tamsayıları tutabilen uint türü bir tamsayı değişkende tutabilirsiniz. uint, 32 bitliktir, tamsayı tutar ama 0 ile 4.294.967.295 arasındaki tamsayıları tutabilir. uint türünde de yine taşma hataları oluşabilir ve bunu yine checked ve unchecked blokları ile muaf tutabiliriz.

Eğer yazdığınız uygulamada, 32-bit sayılar yetmiyorsa, daha büyük ve daha küçük sayıları kullanabilmek için long ve ulong tamsayı türlerini kullanmalısınız. long işaretli 64-bit, ulong ise işaretsiz 64 bit tamsayıdır.

32 bitten daha küçük sayılar tutmak için de tamsayı türleri vardır. short ve ushort tipleri işaretli ve işaretsiz 16-bit tamsayı türleridir. sbyte ve byte ise 8-bit işaretli ve işaretsiz tamsayı türleridir.

System isim uzayının içerisinde Int32, Int16, Int64 gibi yapılar vardır. int, short , long gibi aliaslar yardımıyla da bu yapılara erişebiliriz. Mesela int tamsayı türü aslında Int32 ismiyle System isim uzayında bulunur ama int yazarak ulaşabiliriz. Aşağıdaki tanımlamalardan her ikisi de doğrudur.

int A;


 

System.Int32 A;

Aşağıdaki tabloda .net tarafından desteklenen tamsayı türleri, .net içindeki yapı isimleri ile alabilecekleri en küçük ve en büyük değerler toplu olarak bulunmaktadır.

C# Tür

.NET Yapısı

En Küçük

En Büyük

sbyte

System.SByte

-128

127

byte

System.Byte

0

255

short

System.Int16

-32,768

32,767

ushort

System.UInt16

0

65,535

int

System.Int32

-2,147,483,648

2,147,483,647

uint

System.UInt32

0

4,294,967,295

long

System.Int64

-9,223,372,036,854,775,808

9,223,372,036,854,775,807

ulong

System.UInt64

0

18,446,744,073,709,551,615

.net ailesinde yer alacak dillerin uyması gereken CLS (Ortak Dil Özellikleri), bütün dillerin bir birleri ile haberleşebilmeleri için oluşturulmuştur. .net aliesine katılacak bir dil, en azından bu özellikleri taşımalıdır.

Yukarıda görülen tablodaki SByte, UInt16, UInt32 ve UInt64 tamsayı veri türleri CLS uyumlu değildir. CLS, Byte, Int16, Int32 ve Int64 veri türlerini gereklilik olarak şart koşar ama diğerlerini değil. Bazı diller (mesela Visual Basic.net); Byte, Int16, Int32 ve Int64 haricindeki tam sayı türlerini desteklemez. Eğer diğer diller tarafından da kullanılacak bir dll yazıyorsanız, sbyte, uint16, uint32 ve uint64 veri türlerini kullanmaktan sakınmalısınız. Yoksa, yazdığınız dll mesela Visual Basic .net tarafından kullanılamaz.

Bir int, 32-bit işaretli tamsayı anlamına gelir ama aynı zamanda int, System.Int32 adlı yapının bir örneğidir. Böyle olmasının getirdiği bir takım avantajlar var. Tamsayı türlerini ifade etmekte kullandığımız yapıların ToString ve Parse diye adlandırılan ve en çok kullanılan yöntemleri vardır. Her birinin, MinValue ve MaxValue adında iki tane de alanı vardır.

Alanlar da yöntemler gibidir. Bir yapının ya da sınıfın üyesi olurlar. Ama alan daha basittir. Bunu bir değişken ya da sabit olarak düşünebilirsiniz. Mesela MinValue ve MaxValue alanları sabit değerlere sahiptirler. Program içerisinde alanları sınıfınismi.alanismi şeklinde kullanabilirsiniz. Aşağıdaki program, int tamsayı türünün alabileceği en küçük ve en büyük sayısal değeri ekrana yazar.

1

using System;

2

class Program

3

{

4

static void Main()

5

{

6

Console.WriteLine(Int32.MinValue);

7

Console.WriteLine(Int32.MaxValue);

8

}

9

}

Aynı şekilde diğer tamsayı türlerinin de alabileceği en küçük ve en büyük sayısal değerleri de ekrana yazdırabilirsiniz.

Integer literalleri, hexadecimal notasyonda da yazabilirsiniz. Hexadecimal sayılar, 0x ya da 0X ile başlar ve devamında 16lı sistemde yazılmış bir sayı gelir.

int A = 0x12A4;


 

int B = 0X34CA;

Sınırları aşmamak kaydıyla tamsayı veri türlerini aritmetik işlemlerde birlikte kullanabilirsiniz.

ushort US = 45867;

int I = 523;

int S = US + I;

Yukarıdaki örnekte toplama işlemi meydana gelmeden önce, C# otomatik olarak ushort yapıdaki sayıyı 32-bit işaretli tamsayıya dönüştürür. Çünkü toplama gibi aritmetik işlemler ancak aynı tür iki sayı arasında meydana gelebilir. Daha sonra toplama işlemi yapılır ve sonuç yine 32-bit işaretli bir tamsayıdır.

Burada dönüştürme işlemi programcının müdahalesi olmadan C# tarafından yapılmıştır. Bu tür dönüşümlere kapalı dönüştürme denir.

Eğer derleme evresinde sabit kalacak bir tamsayı sabiti tanımlamışsak, ve tamsayı 8-bit ya da 16-bit bir türdeyse, tanımlanan sabit geçerlidir ama C# onu 32-bit işaretli tamsayıya dönüştürerek derler.

byte B = 120;

Birden çok işlemi içine alan karmaşık bir işlem sırasında, adım adım dönüştürme işlemleri yapılır. Bir atama işlemi sırasında operatörün sağındaki ifadenin türü solundaki ifadenin türüne kapalı dönüştürme ile dönüştürülür. Dönüştürme işlemleri asıl işlemden daima önce yapılır.

Eğer bir int ile bir uint sayı arasında işlem yapılacaksa, C# önce her ikisini de long türüne dönüştürür. Çünkü, hem int hem de uint türünü kapsayan tamsayı türü longdur. Bu durumda aşağıdaki örnek çalışmayacaktır:

1

using System;

2

class Program

3

{

4

static void Main()

5

{

6

uint UI = 45867;

7

int I = 523;

8

int A = I + UI; // Bu satırda derleme hatası oluşur!

9

}

10

}

Hatanın nedeni, işlemin sonucununu int türü bir tamsayıya atamaya çalışmamızdır. Çünkü UI, bir uint türü sayıdır; I ise int türündedir. Bu iki türün bir işlemde kullanılması sonucu oluşacak sonuç long türünde olacaktır ve ancak long türü bir değişkene atanabilir. Oysa yukardaki örnekte sonuç , int türünde bir değişkene atanmaktadır.

Bazen, C# derleyicisinin kapalı dönüştürme yapmak istemediği bir işlemi yapma istersiniz. Bu işlemi yapmak güvenlidir ama C# derleyicisi buna müsaade etmez. O zaman, açık dönüştürme işlemi yaparsınız. Aşağıdaki örnekte bu şekilde açık dönüştürme yapılmıştır ve C# derleyicisi, bu örneği derler.

1

using System;

2

class Program

3

{

4

static void Main()

5

{

6

uint UI = 45867;

7

int I = 523;

8

int A = (int) (I + UI);

9

Console.WriteLine(A);

10

}

11

}

Her bir değişkeni tek tek de açık dönüştürme işlemine tabi tutabilirsiniz. Yukarıdaki örneği incelerseniz, UI adlı değişken uint türündedir ve sadece onu dönüştürerek de int türündeki A değişkenine sonucu atayabilirsiniz.

1

using System;

2

class Program

3

{

4

static void Main()

5

{

6

uint UI = 45867;

7

int I = 523;

8

int A = I + (int) UI;

9

Console.WriteLine(A);

10

}

11

}

Toplama işlemi yapılmadan önce UI değişkeni 32-bit işaretli tamsayı türüne dönüştürüldü ve işlem iki tane 32-bit işaretli tamsayı arasında yapıldı.

Bu tür dönüştürmeye daha çok type casting (tür dönüştürme) de denir. Bundan sonraki yazılarda sadece casting olarak kullanacağız.

Casting işlemi sırasında bit kayıpları da oluşabilir. Mesela bir 32-bit işaretli sayıyı 8-bit işaretli sayıya dönüştürecek olursak 8-bit işaretli tamsayı snırılarını aşan kısım ihmal edilecektir. Eğer aritmetik taşma işlemlerini denetleme seçeneği aktifse çalışma evresinde taşma istisnası oluşacaktır.

Casting işlemi birçok kolaylık sağlar ama suiistimale de açıktır. Kullanırken dikkat etmek gerekir. Oluşabilecek istisnaları yakalayacak yordamlar yazmak gerekir ki, bu işlemin nasıl yapacağını başka bir yazıda ele alacağız.