Makale Özeti

Sayı tabanları arasında değişim yapabilen class

Makale

Merhabalar,

Bu makalede matematiksel taban dönüşümlerini inceleyip .Net platformunda bu işi yapmak üzere yazdığım classın kodlarını ve nasıl işlediğini göreceğiz.

Rakamlar ancak bir sayı tabanında değerlendirildiğinde sayı oluşturabilirler. Bu sayı tabanında değerlendirmeyi yapacak olan nesne sayı basamaklarından başka birşey değildir. Basamağı bir değer olarak düşünürsek beraber telafuz edildiği rakam ile doğru orantılı olarak değerlenecektir. Bir örnekle daha belirginleştirmek gerekirse,Cüzdanımda üzerinde 5 yazan bir para var, Buradan hiçbirşey çıkaramayız çünkü 5 bir rakamdır ve pek bişe ifade etmemektedir. Ancak 5 lira var,5 dolar var tarzı bir kelime ile (kelime burada basamak gibi bir görev görmektedir) bu 5 rakamını betimleyip ona değer katarız. 100ler basamağına yazılan 4 rakamının rakamsal değeri 4 olmasına karşın basamak değeri 4x100=400 dür.

Günlük Matematikte kullandığımız rakam kümesi {0,1,2,3,4,5,6,7,8,9} dur.Ancak bu rakamları yan yana yazarak, yani basamaklandırarak o basamağın değerinin bir çarpanı olarak rol oynamasını sağlarız. Buda bize rakamları kullanarak sayılar üretme yöntemini sunar. Yani bir sayı oluşturmak için rakamlara ve basamaklara ihtiyaç duyarız, uygun basamakta uygun rakamı kullanarak sayıyı elde ederiz.

Bir sayma düzeninde sayma düzeninin boyutu kadar rakam vardır ve bunların en büyüğü basamağın değerinden bir eksiktir. 10luk sayma düzeni 10 rakamdan oluşmaktadır ve bunların en büyüğü 9dur.Sayma düzeninde basamakların aldığı değerler ise sayma düzeninin boyutunun 0dan başayan ve birer birer artan kuvvetleridir. Esasında günlük hayattada farkında olmadan bu yöntemi kullanmaktayız. 10 luk sayma düzenini kullandığımızı göz önünde bulundurarak basamak isimlerine bakalım; birler basamağı= 100=1, onlar basamağı=101=10, yüzler basamağı=102=100 vs vs. O zaman örneğin 7 lik sayma düzeni için ilk basamağın basamak değeri 1(70), ikini basamağın 7(71), üçüncü basamağın49(72) şeklinde devam edecektir.

Bilgisayar dünyasında çok sıkça adını duyduğumuz binary ve hexadecimal sayılarda esasında 2lik ve 16lık sayma düzeninden başka birşey değildir.Ancak 16lık sayma düzenindeki 111 sayısının uc tane 1 denmi yoksa birer tane 11 ve 1 denmi oluştuğu belirsizliği vardır.Bundan dolayı bu sayma düzeninde sayı kümesi {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F} olarak tanımlanır. Yani başka bir değişle A nın rakamsal değeri 10, E nin rakamsal değeri 14 tür. Bir sayının bir sayma düzeninden 10luk düzene çevrilmesini bir örnekle açıklayacak olursak 5 tabanındaki 23104 sayısının günlük hayatta kullandığımız 10luk tabandaki karşılığı için aşağıdaki işlemleri yapmak gerekir;

(4x(50))=4
(0x(51))=0
(1x(52))=25
(3x(53))=375
(2x(54))=1250
-------------------------
Toplamda =1654 olacaktır.

Şimdide bir sayının 10luk sayma düzeninden başka bir sayma düzenine çevrilmesini bir örnekle açıklayacak olursak 10luk sayma düzenindeki 1654 sayısının 5 lik düzendeki karşılığını bulmak için o sayıyı sürekli 5e böleriz.

1654/5 işlemi sonucunda bölüm 330 kalan ise 4 çıkar.
330/5 işlemi sonucunda bölüm 66 kalan ise 0 çıkar.
66/5 işlemi sonucunda bölüm 13 kalan ise 1 çıkar.
13/5 işlemi sonucunda bölüm 2 kalan ise 3 çıkar.
Bölüm Sayısı 2, 5ten küçük oldugundan bölüm sayısının sonunca her adımdaki kalanları sondan başa doğru eklersek aradığımız sonuç olan 23104 çıkar

Ancak Bir sayma düzenindeki sayıyı başka bir sayma düzenine çevirmek istiyorsak ilk önce mutlaka 10luk tabana çevirip oradan hedef tabana gitmeliyiz.Örneğin;5lük sayma düzenindeki 421 sayısınıyı 7 lik düzene çevirmek istiyorsak ilk önce 5lik düzendeki sayıyı 10luk düzene çevirip sonra bulduğumuz sayıyıda 10luk düzenden 7lik düzene çavirmeliyiz.

Şimdi ise bu işlemi yapan classımızı yazmaya başlayalım;


Public Class baseChanger
Public Function ConvertBase(ByVal NumberToConvert As String, ByVal NumbersBase As Short, ByVal TargetBase As Short) As String
Classımızı ve fonksiyonumuzu tanımladık fonksiyondaki parametreleri inceleyecek olursak;
NumberToConvert : Tabanını değiştireceğimiz sayı. Bu değişkenin string olmasının nedeni yukarıda açıkladığımız gibi hexadecimal sayma tabanında harflerinde kullanılmasıdır.
NumbersBase : Verdiğimiz sayının hangi tabanda yazıldığıdır.
TargetBase : Verdiğimiz sayıyı çevirmek istediğimiz hedef tabandır.


Dim basesNumbers() As String = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
Dim NumberConvertedTo10Base As Integer = 0
Yukarıdada anlatıldığı gibi 9 dan büyük rakamları tanımlamak için harfler kullanılır kendimize burada 16 elemanlı bir harf dizisi belirliyoruz en küçük rakamın değer 0 en büyük rakam olan F nin değeri ise 15
NumberConvertedTo10Base : Sayıyı bir sayma düzeninden diğerine çevirmek için arada 10luk tabanı geçiş tabanı olarak kullanmamız gerektiğini söylemiştik.Bu değişken ise geçiş tabanı olan 10luk tabana çevrilmiş sayıyı barındıracak olan değişkendir.


If NumbersBase = 10 Then
NumberConvertedTo10Base = NumberToConvert
Else
For i As Integer = 0 To NumberToConvert.Length - 1
NumberConvertedTo10Base += basesNumbers.IndexOf(basesNumbers, NumberToConvert.Substring(NumberToConvert.Length - 1 - i, 1)) * Math.Pow(NumbersBase, i)
Next
End If
NumberConvertedTo10Base : Sayının ara geçiş düzeni olarak kullanacağımız 10luk düzene çevrildikten sonra değerini tutulacağı değişkendir.
Burada ilk önce if sınamasını niçin kullandığımızı açıklayalım. If sınaması tamamen performansa yönelik bir işlemdir. Fonksiyonumuza gelen sayı 10luk sayma düzeninde ise bu sayıyı bir ara geçiş basamağı olan 10luk düzene bir daha çevirerek kaynak tüketmeye gerek yoktur.
Şimdi If sınamasının else kısmında yeralan ve herhangi bir sayma düzeninde yolladığımız sayıyı 10luk düzene çeviren kodu inceleyelim.;

Bir döngü içerisinde bize gelen string şeklindeki sayının basamaklarındaki rakamları sağdan itibaren birer birer sıra ile alıyoruz(NumberToConvert.Substring(NumberToConvert.Length - 1 - i, 1))
Daha sonra bu aldığımız tek haneli rakamın gerçek rakam değerini bulmak için(10luk ve daha aşağısındaki sayma düzenlerinde bu değer elde ettiğimiz değerler aynıdır. Ancak hexadecimal bir sayı için düşünürsel gelen değer B ise gerçek rakam değeri 10lu düzene çevirirken 11 dir.) Dizi içerisindeki sırasından faydalanıyoruz. (B dizide 11. sırada olduğu için değeride 11 olmuş oluyor.)
Bir sonraki adımda ise sayının basamak değerlerini hesaplatıyoruz(Math.Pow(NumbersBase, i)) ve bunu o basamakta bulunan rakamın sayısal değeri ile çarparak bize esasında hangi değeri belirtmek istediğini buluyoruz.
Bu değerleri her basamak için tek tek bulduktan sonra hepsini toplayarak sayının 10luk düzendeki değerini bulabiliriz.


Dim NumberConvertedToTargetBase As String
If TargetBase = 10 Then
NumberConvertedToTargetBase = NumberConvertedTo10Base.ToString
Else
Do Until NumberConvertedTo10Base = 0
NumberConvertedToTargetBase = basesNumbers((NumberConvertedTo10Base Mod TargetBase).ToString) & NumberConvertedToTargetBase
NumberConvertedTo10Base = Math.Floor(NumberConvertedTo10Base / TargetBase)
Loop
End If
NumberConvertedToTargetBase : Bu değişkende geçiş düzlemi olan 10luk tabandan hedef tabana çevirdiğimiz sayıyı saklayacağız.
Bu kısımda bulunan If sınamasıda tamamen performansa yönelik bir uygulamadır. Fonksiyonun sayıyı çevirmesi gereken taban 10luk taban ise geçiş tabanında elde ettiğimiz sayı zaten 10luk tabanda olduğundan bir daha işlem yaptırmadan direkt bu sayıyı geriye döndürebiliriz.
Şimdi sayıyı 10luk tabandan hedef tabana çevirmek için yazmış olduğum kodu incelersek;
Hatırlarsak sürekli hedef tabana bölme işlemi yaparak kalanları ve en son işlemdeki bölümü kullanarak sayıyı elde ediyorduk.O zaman bölüm değerimiz 0 sayısını verene kadar bölme işlemi gerçekleştirmeliyiz vede bunu do until ile sağlıyoruz.
Bir sayının başka bir sayı ile bölümünden kalanını bölünen sayının bölen sayı modundaki değerine eşittir.Ara basamak olarak 10luk düzende bulunan çevrilecek olan sayımızın hedef sayı tabanına bölümünden kalan sayıyı bulmak için mod kulllanırız. Vede bu değerleri sürekli bir şekilde öncekinin önüne eklenecek şekilde birleştiririz.
Evet bölme işlemini yaptık ve kalanı bulduk ancak bölme işlemi bölüm üzerinden devam edeceği için bölüm değerinide hesaplatıp değişkende tuturuyoruz for döngüsünün bir sonraki adımında bu değişken hedef sayı tabanına bölünüp kalan tekrar ve tekrar taaki bölüm 0 olana kadar alınacaktır.


Return NumberConvertedToTargetBase
End Function
End Class
Fonksiyonumuza en son hesaplattığımız değeri döndürtüp işlemi bitiriyoruz.Bu kod yapısında kullanıcının 16 dan büyük bir sayı tabanı yollaması durumunda veya dizide bulunmayan bir değer yollaması( örn. u,y,t)durumunda veya yolladığı sayının basamaklarında taban değerine eşit veya büyük sayı bulunması durumunda hatalar oluşabilir. Bu hatalar için gerekli koruma bu kod ögrenim amaçlı olduğu için basitliğini va anlaşılabilirliğini bozacağından yazılmamıştır.

Kodları indirmek için tıklayın.

Tamer ÖZ

oztamer@hotmail.com
tamer.oz@yazgelistir.com
oztamer@hotmail.com