Yazan : Şadi Evren ŞEKER
Bilgisayar yapılarında ondalıklı sayıları ( floatingpoint numbers ) iki farklı bilginin tutulması ile gösterilebilir:
mantis x kök üst
yukarıda verilen formüle göre bir ondalıklı sayıyı önce bir ondalık çarpan sonra da bir kök’ün verilen üstü ile çarpımı olarak göstermek mümkündür.
Örneğin ikilik tabanda 1101.11 küsurlu sayısını ele alalım (“.” işaretinden sonraki kısım küsurudu). Bu sayıyı göstermek için öncelikle bütün sayıyı önce 4 hane ilerleterek (kaydırarak, float) sayının tamamını küsurlu hale getirelim:
.110111
Yukarıdaki bu sayının orjinal değerini taşıyan gösterimi
.110111 x 2 4
olmalıdır çünkü orjinal sayının 4 hane kaydırılmış halidir. Dolayısıyla sayımızı aşağıdaki iki tamsayıyı tutarak göstermek mümkündür:
mantisa (mantissa) : 110111
üst (exponent) : 0100 (onluk tabandaki 4′ün karşılığı)
Merve Hanımın soruları üzerine aşağıdaki kısmı eklemenin gerekli olduğu anlaşılmıştır:
Kayan noktaların gösterimi
Konuyu örnek bir sayı üzerinden anlamaya çalışalım. Örneğin sayımız 123.321 olsun.
Sayımızın tam kısmı 123′tür küsurat kısmı aşağıdaki şekilde yazılabilir:
3*10 -1 + 2*10 -2 + 1*10 -3
Bu düşünce, bizim alıştığımız onluk sistemdeki yaklaşımdır. Bu sayının ikilik tabana nasıl çevrileceği ile ilgili olarak “ Ondalık sayıların taban dönüşümü” başlıklı yazıyı okuyabilirsiniz.
Ayrıca yukarıdaki sayımızı bilimsel gösterimde aşağıdaki şekilde yazabiliriz:
1.23321 * 10 2
Tek hassasiyetli (single precision) kayan nokta sayısı, 32 bitlik bir paket olarak düşünülebilir. Bu yapı aşağıdaki tabloda temsil edilmiştir:
X |
XXXXXXXX |
XXXXXXXXXXXXXXXXXXXXXXX |
| Yön
Sign |
Üst
Exponent |
Kök
Mantissa |
Yön biti (sign bit)
Bu bit 1 olduğu zaman, sayımız – değerdedir. Şayet 0 veya artı değerde bir sayı ise, bu bit 0 olur.
Üst Biti (Exponent Bit)
Yukarıdaki örnekte gösterilen bilimsel yazıma göre, sayının üst değeri bu alanda tutulur. Buna göre bir sayının 2′nin kaçıncı kuvveti ile çarpılabileceğini gösterir.
Burada dikkat edilecek bir husus, üst değerinin de eksi olabileceğidir. Örneğin sayımız 0.000123 ise, bu sayının bilimsel gösterimi : 1.23 * 10 -4 olacaktır.
Bu durumda 8 bitlik alanın ilk biti yön bilgisi tutmaktadır. O halde geriye kalan 7 bit, üst bilgisi tutabilir. Buradan çıkan sonuç, sayımızın en fazla 127. üstüne kadar olan değerin tutulabileceğidir (2 7 =128 olduğunu ve bu bilginin ilk değerinin 0 için ayrıldığını dolayısıyla, sayımızın 0 – 127 arasında olacağını hatırlayınız).
Kök biti (mantissa bit)
23 bit alan kaplayan kısımdır. Bu alana bazı durumlarda belirgin anlamına gelen (significand) ismi de verilir. Bu kısım bilimsel gösterimin kök kısmıdır. Örneğin 1.23 * 10 -4 sayısı için kök kısmı 123 olacaktır.
Örnek sayı
Yukarıdaki alanların, bir örnek sayı için nasıl gösterildiğine bakalım:
21,25 sayısını çevirmeye çalışalım. Öncelikle bu sayının ikilik tabandaki karşılığını bulalım:
10101.01
Bu sayıyı, bilimsel gösterime çevirelim:
21,25 = 2,125 * 10 -1 = 2125 * 10 -3
Ayrıca son bir bilgi : (2125) 10 = (1000010001101) 2
Şimdi bu sayının hafızadaki tutuluşuna bakalım:
Yön bitimiz, sayımız pozitif olduğu için 0 olacak.
Üst bitlerimiz, sayının üstü -3 olduğu için 100000011 olacak. Buradaki son iki bit 3 değerini, baştaki bit ise yönün eksi olduğunu göstermektedir.
Geriye kalan alan ise kök değerini tutacaktır.
(21) 10 = (10101) 2 olduğuna göre,sayımız aşağıdaki şekilde gösterilebilir:
0 |
10000011 | 01010100000000000000000 |
| Yön
Sign |
Üst
Exponent |
Kök
Mantissa |
Sonuç olarak sayımız:
01000001101010100000000000000000
şeklinde bulunmuş olunur.
Çift hassasiyet ve tek hassasiyet ( double precision , single precision)
Yukarıdaki yazı, tek hassasiyet dikkate alınarak hazırlanmıştır. Bunun anlamı sistemin 32 bit olmasıdır. Sistem 64 bit olabilir. Bu durumda çift hassasiyetten bahsedilmelidir. İki sistem arasındaki fark, aşağıdaki şekildedir:
1 bit yön biti (sign bit)
8 bit üst değeridir (exponent)
23 bit kök değeridir (mantissa)
64bitlik bir sistemde ise durum aşağıdaki şekildedir:
1 bit yön bitidir (sign bit)
11 bit üst değeridir (exponent)
52 bit kök değeridir (mantissa)
Kayan nokta gösteriminden Onluk sisteme çevirim
Bu çevirimi anlamak için bir örnek üzerinden konuyu anlatalım.
Çevirmek istediğimiz sayı, 0xC0B40000 olsun. Bu sayı onaltılık tabandadır (hexadecimal) ve aşağıdaki şekilde ikilik tabana (binary) çevirilebilir:
| Onaltılık | C | 0 | B | 4 | 0 | 0 | 0 | 0 |
| İkilik |
1100 |
0000 |
1011 |
0100 |
0000 |
0000 |
0000 |
0000 |
Yukarıdaki çevirimden çıkan ve tek hassasiyetli (single precision) gösterim aşağıda verilmiştir:
1 |
10000001 |
01101000000000000000000 |
Demek ki sayımız eksi bir değermiş (en baştaki yön biti 1 olduğu için) ve ayrıca üstü de eksi imiş (yön bitini tutan grup 1 ile başladığı için).
Gelelim kök kısmının (mantissa) dönüşümüne.
Kök kısmımızdaki değer, 01101 olarak bulunuyor. Bu değeri yukarıdaki bilgiler ile birleştirirsek aslında sayımız aşağıdaki şekildedir:
-1.01101 * 2 2
Artık problemimiz bu sayıyı onluk tabanda göstermektir. Sayının her basamağının üst değerini yazalım:
-(2 0 + 2 -2 + 2 -3 + 2 -5) * 2 2 = -(2 2 + 2 0 + 2 -1 + 2 -3)
değerleri hesaplayalım:
-(4 + 1 + .5 + 0.125) = -5.625
561 views

İyiydi teşekkürler
Hocam merhaba, öncelikle bilgilendirmeniz için teşekkürler. Ben de bir yerde görmüştüm merak ettim. Mesela;
-2 sayısının binary, hexadecimal, truncation, precision value of the real number olarak sırasıyla şu şekilde göstermiş :
11000000 10000000 00000000 00000000
C0 80 00 00
-2,0
-2,0 +-0,0
C programlama dilinde bunlar için kullanabileceğimiz fonksiyonlar mevcut mudur, yoksa nasıl bu şekilde gösteriliyor? Yanıtlarsanız çok sevinirim.
ANSI C için, ne yazık ki bu şekilde çevirim yapan hazır fonksiyonlar yok. Ancak bazı özellikler belki işinize yarar.
Örneğin, herhangi bir sayıyı %x ile bastırırsanız hexadecimal (onaltılık) karşılığını alırsınız.
#include <stdio.h> int main(){ int c = 123; printf("sayi :%d",c); printf(" onaltili: %x",c); return 0; } ~Yukarıdaki kodun çktısı aşağıdaki şekildedir:
sayi :123 onaltili: 7b
Truncate işlemi için (kesme), tam sayılardan faydalanabilirsiniz:
#include <stdio.h> #include <math.h> int main(){ float c = -2.3433; printf("sayi :%f",c); int tamkisim = c*100; c = (float)tamkisim / 100; printf(" kesilmis : %f",c); return 0; } ~Yukarıdaki kodun çıktısı :
sayi :-2.343300 kesilmis : -2.340000
Yukarıdaki kodda, float sayının 100 mislinin (virgülün iki kaydırılmış halinin) tam sayıya çevrilerek (ki bu anda virgülden sonra kalan diğer değerler kaybolur) ardından float sayıya geri döndürülmesi söz konusudur.
C dili için yukarıdaki durum söz konusu iken JAVA gibi gelişmiş dillerde bu isteklerinizi yapan fonksiyonlar bulunmaktadır.
Örneğin aşağıdaki kod bu çevirimleri yapmaktadır:
public class deneme{ public static void main(String args[]){ int x = 123; System.out.println(Integer.toBinaryString(x)); System.out.println(Integer.toHexString(x)); } }Yukarıdaki kodun çıktısı aşağıdaki şekildedir:
1111011
7b
Gelelim float sayıların çevirimine. Ne yazık ki JAVA’da bulunan Float, kılıf sınıfının (wrapping class) doğrudan bir dönüşüm fonksiyonu yok. Yani Intger.toBinaryString() der gibi Float.toBinaryString() diyemeyiz. Bu problemi çözmek için biraz daha uğraşmamız gerekiyor:
public class deneme{ public static void main(String args[]){ Float f = 123.456f; System.out.println(f); System.out.println(Integer.toHexString(Float.floatToIntBits(f))); } }Çıktısı :
123.456
42f6e979
Görüldüğü üzere istenilen amaca göre elimizdeki dilin özelliklerini kullanmamız gerekiyor. Genelde floating numbers (kayan nokta sayıları) yakın bir değer tutarlar ve tam değer bulundurmazlar. Bu anlamda, programlama dilleri açısından çoğu zaman problem oluştururlar. Ancak istenilen amaç tam olarak belirlendikten sonra o dildeki özelliklere göre kullanılabilirler.
başarılar
Cevabınız için çok teşekkürler hocam. Peki sayının 32 bitlik gösterimi için nasıl bir yol izlemeliyiz? Kolay gelsin.
sayılar zaten tanımlı olduğu işletim sistemi / derleyici (compiler) ortamına bağımlıdır. Siz normalde bir değişken tanımladığınızda o ortamdaki değerlere göre tanımlanır.
Öncelikle 32 bit olması durumunda sayıda nasıl değişiklik oluyor ona bakalım.
Örneğin sayımız 2 olsun. Bu sayının ikilik tabandaki karşılığı 10 olarak gösterilir. Ancak 32 bit olan bir sistemde 0000 0000 0000 0000 0000 0000 0000 0010 şeklinde görülür. Yani sistem 32 bittir.
Biraz daha ilerleyerek -2 sayısını irdeleyelim. Bu sayı yönlü bir sayıdır (signed). Dolayısıyla 32 bitlik yerin bir biti yöne ayrılır. Bu bit en baştaki bittir:
1000 0000 0000 0000 0000 0000 0000 0010
Görüldüğü üzere sadece baştaki bit eksi sayılar için 1 diğer sayılar için (0 ve artı sayılar) 0′dır.
Ancak sayı eksi sayı olarak tanımlanıp sonra on altılık sisteme çevirilirse, baştaki değerin yön biti olduğu bilgisi kaybedilerek baştaki değer de çevirilir.
Bu durumu aşağıdaki kod üzerinden anlamaya çalışalım:
#include <stdio.h> #include <math.h> int main(){ int c = -2; printf("sayi :%d",c); printf(" onaltilik : %x",c); return 0; }Yukarıdaki kodun çıktısı aşağıdaki şekildedir:
sayi :-2 onaltilik : fffffffe
Görüldüğü üzere, sayı -2′dir ve 0 – 2 işleminin sonucu olarak düşünülür. bu durumda -1 değeri, 32 bitlik sistemdeki en büyük değer olan ff ff ff ff ile aynıdır. -2 değeri ise bu sayının bir eksiği olan ff ff ff fe olarak gösterilmiştir.
Yukarıdaki bu durum elbette 32 bit için geçerlidir.
Kısacası 32 bit bir sistemde ilk bit yönlü sayılar için yön bitidir (sign bit) ve sonraki bitler (geri kalan 31 bit) veri için kullanılır.
Gelelim kayan nokta sayılarına (float numbers). 32 bit bir sistemde durum aşağıdaki şekildedir:
1 bit yön biti (sign bit)
8 bit üst değeridir (exponent)
23 bit kök değeridir (mantissa)
64bitlik bir sistemde ise durum aşağıdaki şekildedir:
1 bit yön bitidir (sign bit)
11 bit üst değeridir (exponent)
52 bit kök değeridir (mantissa)
Aslında bütün bunlardan sonra yazıya tekrar baktım da, sanırım yazıda bu konuları anlatmakta fayda var. Birazdan yazıya gerekli eklemeleri yapıp konunun daha iyi anlatıldığı bir örnek veririm.
başarılar
Hocam verdiğiniz bilgiler çok faydalı, teşekkür ederim öncelikle. Merak ettiğim iki floating point sayısı üzerinde (32 bitlik gösterimde) dört işlem (toplama, çıkarma, çarpma, bölme) nasıl gerçekleştirilebilir? Yanıtlarsanız çok sevinirim. Kolay gelsin.
yuvarla float , kacbasamak)
Virgülden sonra kaç basamak yuvarlamak istiyorsak o kadar yuvarlayan fonksiyonu tasarlamak istiyorum hocam .
ORNEK Yuvarla(3.454556,4)
yardımcı olursanız sevinirim tesekkurler
Basit bir müsvette kodu (pseudo code) aşağıdaki şekilde yazabilirsiniz:
float yuvarla(float a, int b){ int carpan = 10; for (int i = 0;i< b;i++) carpan *= 10; int tam = a*carpan; a = (float)tam / (float)carpan; return a; }Başarılar
merhaba 8 lik tabandaki 44,44 sayisini nasil 4 luk tabana cevirebiliriz…
Sorunuzun cevabı için lütfen ilgili yazıları okuyunuz.
http://www.bilgisayarkavramlari.com/2008/10/17/sayi-tabanlari-number-bases/
http://www.bilgisayarkavramlari.com/2009/10/08/sayi-tabanlari-number-bases-2/
http://www.bilgisayarkavramlari.com/2011/04/01/ondalikli-sayilarin-taban-donusumleri/
Başarılar