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
1 bit

Üst

Exponent
8 bit

Kök

Mantissa
23 bit

 

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
1 bit

Üst

Exponent
8 bit

Kök

Mantissa
23 bit

 

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

Yorumlar

  1. Merve

    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.

  2. Şadi Evren ŞEKER Article Author

    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.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #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:

    1
    2
    3
    4
    5
    6
    7
    
    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:

    1
    2
    3
    4
    5
    6
    7
    
    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

  3. Merve

    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.

  4. Şadi Evren ŞEKER Article Author

    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:

    1
    2
    3
    4
    5
    6
    7
    8
    
    #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

  5. Ecem

    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.

  6. gokhan.taskin

    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

  7. Şadi Evren ŞEKER Article Author

    Basit bir müsvette kodu (pseudo code) aşağıdaki şekilde yazabilirsiniz:

    1
    2
    3
    4
    5
    6
    7
    8
    
    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

  8. ayşe

    iyi günler hocam..5D6B+F8EA toplamını nasıl buluruz.(1bit işaret biti,10bit kesir,5bit üs olacak).teşekkürler
    -->binary halde yazıp eşitlemek için kaydırma yapılmıs ama anlamadım..

  9. Şadi Evren ŞEKER Article Author

    Bakın sayıları ikilik tabana çevirelim öncelikle :

    5D6B = 0101 1101 0110 1011
    F8EA = 1111 1000 1110 1010

    şimdi ilk bit işaret biti ise sonraki 10 bit sayı ve 5 bit üs ise sayıları bu verilen kısımlara göre parçalayalım:

    5D6B = 0 (+) 101 11 ( sayı ) 01 0110 1011 (üs)
    f8EA = 1 (-) 111 10 ( sayı ) 00 1110 1010 (üs)

    onluk tabana çeviriyorum ki anlaşılsın (kaydırma işlemini anlamadığınız için buna yoğunlaşalım)

    5D6b = + 23E363
    F8EA = - 30E234

    Görüldüğü gibi aslında işlem 363. dereceden 23 sayısından 234. dereceden 30 sayısının çıkarılmasıdır. Bu işlemlerin yapılabilmesi için aynı dereceye indirgenmesi gerekir. Bu da kaydırma işlemini gerektirir. Önce sayılar aynı üsse getirilip sonra işlem yapılmaktadır.

  10. ela

    hocam 100 lük bir tamsayı dizisinde 32 bitlik sayılar var bizden istenen o sayıların ilk 6 biti ile son 6 bitini karşılaştıran bir fonksiyon nasıl yapabilirim yardımcı olur musunuz?

  11. Şadi Evren ŞEKER Article Author

    karşılaştırıp eşitlik mi kontrol edecek.

    iki sayının xor değerini alıp 61455 ile and işlemine tabi tutun sonuç 0 ise eşitler demektir.

    örnek:

    1
    2
    3
    
    int f(int a, int b){
      return (a ^ b) & 61455; 
    }

    eşit olduklarında 0 döndürür.

    not: 61455 = ilk 6 ve son 6 biti 1 olan 32 bitlik sayının 10luk tabandaki karşılığı.

    Başarılar

  12. sena

    Sayın Hocam single-precision binary floating-point formatta exponent kısmının 8 bitten oluştuğunu biliyoruz ve siz bunun msb bitinin işaret biti olduğunu söylemişsiniz."Bu durumda 8 bitlik alanın ilk biti yön bilgisi tutmaktadır" bu durumda range :-128 ile +127 arasında olmazmı , burada +127 ile üstün toplanmasının mantığı nedir.
    Teşekkürler...

  13. Şadi Evren ŞEKERŞadi Evren ŞEKER

    Sena Hanım,
    Sanırım bahsettiğiniz gösterimi IEEE 754 ile karıştırıyorsunuz. IEEE standardı olan bu gösterim (binary32 olarak da geçmektedir) yukarıdaki anlatımdan biraz farklı.
    Farkı hızlıca açıklamaya çalışayım:
    Yine 1 + 8 + 23 bitten oluşan 3 kısımımız var.
    Yön biti: Yukarıdaki anlatım ile aynı ve soldan ilk bittir.
    Üst kısmı (exponent): 0 değeri 127 olacak şekilde kabul edilir. Dolayısıyla herhangi bir değerin 127'den çıkarılması gerekir. Örneğin üst değerinin -3 olduğu durumda üst değeri 124 = (1111100)2 olacaktır.
    Bölüm kısmı (Fraction) : Mantissa'dan tamamen farklı. Sayının kaça bölüneceğini belirtir.

    Yukarıdaki 3 bölüme göre gösterim yapılır ardından onluk sayıya çevrilme işlemi sırasında aşağıdaki yöntem izlenir:
    yön biti 1 ise sayı - , 0 ise + kabul edilir
    Üst kısmının onluk tabana çevirimi yapılır ve 2'nin üzeri olarak hesaplanır (diyelim ki üst biti ü olsun 2ü değeri hesaplanır ve aşağıda anlatılacak olan bölüm bitinden gelen değer ile çarpılır)
    Bölüm kısmı öncelikle 1 ile başlar, yani bütün haneler 0 bile olsa değer 1'dir. Ayrıca kaçıncı hane ise 2 üzeri - değer olarak hesaplanır ve bu değerler toplanır. (diyelim ki 23 haneli bölüm biti için 1. ve 5. bitler 1 diğer bitler 0 olsun. Bu durumda hesaplanacak olan sayı 2-1 + 2-5 olacaktır bu değer hesaplanıp 1 ile toplanarak üst bölüm kısmı bulunur)

    Buna göre örnek olarak aşağıdaki sayıyı ele alalım:

    1 01111100 0000000000000000001001010

    Bu 4 byte (32 bit) uzunluğundaki sayıyı 10'luk tabana çevirme işlemini adım adım yapalım:

    yön biti 1 dolayısıyla sayı -1 ile çarpılacak

    üst kısmı (01111100)2 = (124)10
    dolayısıyla bu sayıdan 127 çıkarıp 2 üzeri olarak hesaplayacağız yani 2124 - 127 = 2-3 olarak sayıyı buluyoruz. Bu sayı 0.125 değeridir (bunu bulmak için şu şekilde hesap yapabilirsiniz. Öncelikle 23 hesaplanır = 8 sonra 1/8 hesaplanır = 0.125)

    Bölüm kısmı 1 ile başlıyordu ayrıca 1, 3 ve 7 bitlerde 1 taşıyor o halde aşağıdaki hesabı yapacağız:
    1 + 2-1 +2-3 +2-7
    Bu değerleri sırası ile çevirerek bulalım
    1 + 0.5 + 0.125 + 0.0078125 (çevirirken daha önce anlattığım gibi sayının önce üstü + gibi kabul edilip 2 üzeri şeklinde hesaplanıyor sonra 1'i bu değere bölerek buluyoruz)

    Yukarıdaki toplam yani 1 + 0.5 + 0.125 + 0.0078125 = 1.5328125 olarak bulunur.

    şimdi 3 kısmı birleştirelim

    -1 x 0.125 x 1.5328125 = - 0.1916015625

    olarak sayının onluk tabandaki gösterimini buluruz.

    Umarım sorunuzu doğru anlamışımdır.

  14. sena

    Hocam cevabınız için teşekkür ederim.Exponent_part bulunurken offset_binary yöntemi kullanılıyor bu değer 8 bit için bias: 127 ,double precision fp de ise 11bit exponent part için bu değer 1023
    işte ben bu değerlerin nereden bulunduğunu ve mantissa deyimi ile fraction deyimi arasındaki farkı merak ediyorum.

    1.b0b1*2^x (normalizasyon yapıldıktan sonra) sayısının Single Precision FP gösterimini elde ederken
    bias değeri 127 olan 8 bit lik bir alanda x değeri en fazla 128 olmazmı ? 127+128=255
    yani bias değeri 127 olan 8 bitlik bir alana girilebilecek en büyük ve n küçük sayı nedir?

    çok sağolun iyiki varsınız ?

  15. ahmet

    Hocam bn 1 snf ogrncsym hoca odev verdi ama yapmyrm yardmci olrsnz sevinrm soru su -130207076 10 tabanndaki sayiyi float point 32 bite ve fix pointe cevir 2 lik tabana

  16. Şadi Evren ŞEKERŞadi Evren ŞEKER

    Sena Hanım

    Sorunuzu tam anlayamıyorum. Tahmin ettiğim şeyi soruyorsanız cevabı şöyle. Exponent (Bias, üst) değeri hesaplanırken 8 bitlik bir alan var doğru. (bias ile exponent ieee standardında aynı, daha doğrusu ieee üst değeri olarak biased değer kullanıyor)

    İkilik tabandaki bir alana konulabilecek max sayı 2k-1 formülü ile hesaplanır (k hane (digit, bit) sayısı olmak üzere). Dolayısıyla bizim 1 bitimiz yön (sign) gittiği için biz 7 bitlik alana ne koyabiliriz diye bakıyoruz ve 27-1 ile 127'yi buluyoruz.

    Yani karıştırdığınız nokta 27-1 yerine neden 27 kullanmadığımız ise buradaki 1 bit 0 gösterimine gidiyor. Mesela 1 bitlik bir alanımız olsa 0 ve 1 gösterebileceğimiz için max 1 değeri alabilir, 2 bit için max değer 3'tür.

    Ancak eksi değerler için 0 gösterme derdi yok dolayısıyla 128 değeri olarak gösterilebilir (yani 8 bitlik alan 1111 1111 değerine sahipse baştaki 1 eksi ve sonraki 7 bit ile sayının onluk tabandaki karşılığı -128 olur). Buna karşılık 0111 1111 sayısının değeri +127 olur.

    IEEE bu değeri 127 biased olarak kullanıyor. Yani bir anlamda 127 değeri kadar kaydırıyor ve 2e-127 formülü ile hesaplıyor. Mesela aşağıda bir iki örnek veriyorum:

    -1 için -1 + 127 = 126 = (01111110)2
    0 için 0 + 127 = 127 = (01111111)2
    +1 için +1 + 127 = 128 = (10000000)2
    +7 için +7 + 127 = 134 = (10000110)2

    Başarılar

  17. Şadi Evren ŞEKERŞadi Evren ŞEKER

    Ahmet Bey,

    Ödevinizi sizin için çözmem doğru olmaz, dilerseniz ödevinizi yaptıktan sonra doğruluğundan emin olmak için herhangi bir hesap makinesi ile veya internette bulacağınız çok sayıdaki araç ile sonucu kontrol edebilirsiniz.

    Başarılar

  18. Furkan Mücahit Kandaz

    hocam -130,208033 gibi uzun negatifleri virgülden sonrasını nasıl yapıcamızı anlamadım yada pozitifiini nasıl negatife çevirebiliriz

  19. kübra

    meraba hocam ben bu konuyu yenı ogrenıyorum ve surda zorluk cektım 23,15 sayısını 34 bitte tablolam kısmı kok bıt yan kok seklınde o 1 ve sıfıların nasıl olustugu nasıl yapacagını gosterebilrmisniz

  20. Şadi Evren ŞEKERŞadi Evren ŞEKER

    Soruların hepsi için genel olarak yazıyorum. Bakın çok basit bir konu ve elimden geldiğince basit anlatmaya çalışacağım. Şayet aşağıdaki yazıyı anlarsanız her türlü sayıyı kağıt kalem ile çevirebilirsiniz (tamam biraz karmaşık sayılar için 4 işlem yapan bir hesap makinesi de gerekebilir 🙂 )

    Bakın 32 bit gösterim var. ilk bit yön biti (sign bit) eksi ise 1 değilse 0 olacak.
    sonraki 8 bit üst biti. Yani 2'nin bir üstü olur. Bunlar 1,2,4,8,16,32 diye giden seridir. Bu seri eksi veya artı olabilir, yani aynı seriyi -1,-2,-4,-8 şeklinde düşünebilirsiniz.
    Sonraki 23 bit ise mantissa. Burası çarpanı oluşturuyor.

    Daha iyi anlaşılması için basit sayılar üzerinden göstereyim. Öncelikle mantissa ile uğraşmadan onu hep sıfır alalım, mantisa 0 onluk sistemde 1'e karşılık gelir kuralı ile başlayalım.

    Mesela onluk sistemdeki 1 sayısını çevirirseniz yön biti 0, mantissa 1 ve üst 20 olmasını istersiniz. Bunun IEEE 754 için anlamı yön biti 0, üstü 20 olduğu için 0000 0000 olan 8 bitin complimenti yani 0111 1111 olan sayı (tam hesaplamak için 127 - bu sayı şeklinde düşünmek gerekiyor yani 127'den çıkarmak gerekiyor) ve mantissa 1 olduğu için tamamı sıfırdan oluşan 23 bit.
    Yani (1.0)10 = (0 0111 1111 0000 0000 0000 0000 0000 000 )2 olacaktır.

    Mesela 0.5 sayısını çevireckeseniz sayı basitçe + 2-1 * 1 olacak. Bu sayının IEEE 754 gösterimini adım adım hesaplayalım.
    Öncelikle yön biti 0 olacak çünkü sayı pozitif.
    Üstü -1 olacak bu da normal ikilik tabanda yön biti 1 olan 1 sayısıdır ki 8 bit için 1000 0001 olarak gösterilir (ilk bit yön biti son bit ise sayının değeri) bunun complimenti 0111 1110 olur ve son olarak mantissa 1 olacağı için 23 adet sıfır değerine sahip oluruz
    Yani (0.5)10 = (0 0111 1110 0000 0000 0000 0000 0000 000 )2 olacaktır.

    Bu şekilde devam edersek, örneğin 0.25 aslında 1/4 olduğu için + 2-2 * 1 olacaktır o halde çözüm (0.5)10 = (0 0111 1101 0000 0000 0000 0000 0000 000 )2 olacaktır. (üst bitine dikkat ediniz)

    Demek ki sayıyı 2'nin bir üstü ile çarpım olarak düşünmemiz gerekiyor. Aynı durum zaten tam sayılar için de geçerli. Mesela 8 için
    (8)10 = (0 1111 0111 0000 0000 0000 0000 0000 000 )2 olacaktır. Yani üst kısmı 8 olan mantissa 1 olan yön biti 0 olan sayı yani 2+8 * 1 olacaktır.

    Şimdi mantissayı da ekleyelim hesaplarımıza. 23 bitlik kısım olduğunu biliyoruz. Bunun çok basit bir kuralı var ilk bit yarım ikinci bit çeyrek şeklide gidiyor. Yani 23 bitlik seride hepsi sıfır ise

    0000 0000 0000 0000 0000 000

    20 = 1 oluyor.

    Diyelim ki ilk bit 1 oldu o zaman 21 = 2 oluyor ama biz bu sayıyı 1/ şeklinde düşünüyoruz ve 1/2 = 0.5'tir diyoruz ve bu sayıya mantissa için her zaman 1 ekliyoruz.

    1000 0000 0000 0000 0000 000

    Aşağıda farklı mantissa değerlerinin onluk karşılığını veriyorum.

    0100 0000 0000 0000 0000 000 = 1.25 yani 1/4 + 1
    1100 0000 0000 0000 0000 000 = 1.75 yani 1/2 + 1/4 + 1
    0010 0000 0000 0000 0000 000 = 1.125 yani 1/8 +1 = 0.125 + 1

    Sanırım anlaşılıyor. yani mantissa değerini sağdan sola doğru verdiğiniz değere göre üssel negatif düşünmeniz gerekiyor.

    Ayrıca yukarıdaki bütün sayıların başına 0 yön biti ve 0 üst biti eklerseniz doğrudan IEEE 754 gösterimi elde edersiniz. Yani

    0 000 0000 0100 0000 0000 0000 0000 000 = 0.25 yani + 21 * 1/4 gibi.

    Şimdi daha karşamış sayılara geçelim. Öncelikle tam sayı kısmının artması durumuna bakalım. Herhangi bir sayı için onluk tabandaki sayının öncelikle 2'lik tabandaki üstünü bulmanız gerekiyor. Mesela sayı 4 ile 8 arasında ise 4, 8 ile 16 arasında ise 8 şeklinde o sayıya en yakın 2'nin üstünü almanız gerekiyor. Diyelim ki IEEE 754 çevireceğimiz sayımız 6 olsun. 2'nin 2 ile 2'nin 3. kuvvetleri arası olduğu için (4 ile 8 arasında) alttaki olan değer olan 2'yi alıyoruz. Bu durumda sayımızın ilk biti (yön) 0 olacağını ve üstünün 2 olacağını anlıyoruz (karıştırmak istemediğimden girmiyorum ama aslında 2'lik tabanda logaritmasını alıyoruzda denilebilir) yani ilk 9 bit aşağıdaki gibidir diyebiliriz:

    0 1000 0001

    şimdi geri kalanını bulalım. Elimizdeki sayılara bakarsak 6 = 22 * x gibi bir denklemimiz var yani 6 = 4 * x denkleminde x ne olur? Cevap 1.5 (6/4 şeklinde hesapladık)

    Eh virgülden sonraki değerimiz .5 olduğuna göre basitçe mantissanın ilk biti 1'dir diyebiliriz (1/2 = 0.5 olduğu ve mantissanın ilk bitinin 21 = 2 olduğu için (yukarıdaki mantissa örneklerini hatırlayın)). Dolayısıyla 6 sayısının ieee 754 gösterimini elde etmiş oluyoruz:

    0 1000 0001 1000 0000 0000 0000 0000 000 = + 21 * 1.5

    Şimdi Kübra hanımın sorusuna geçelim. Soruyu biraz basitleştirelim ve 23 tam sayısını nasıl çeviririz bakalım.

    23 sayısı, 24 ile 25 arasında yani 16 ile 32 arasında yer alıyor. O halde bizim üst değerimiz 4 olacak. Eh ilk 9 biti hesapladık bile

    0 1000 0011 (üstel olarak 127 - 4 gösterimi şeklinde de düşünebilirsiniz).

    Geriye ne kaldı bir bakalım. elimizdeki denklem şöyle:

    23 = 24 * x
    yani 23 = 16x denklemindeki x'i bulacağız.

    23/16 = 1.4375 olacaktır. Şimdi mantissa ile 1.4375 nasıl gösterilir ona bakmamız gerekiyor.

    Bakın sayıları beraber ilerletelim mantisaa değerlerini yazıyorum:

    0000 0000 0000 0000 0000 000 = 1
    1000 0000 0000 0000 0000 000 = 1.5 (aslında 1 + 0.5)
    0100 0000 0000 0000 0000 000 = 1.25 (aslında 1+ 0 + 0.25)
    1100 0000 0000 0000 0000 000 = 1.75 (aslında 1+ 0.5 + 0.25)
    0010 0000 0000 0000 0000 000 = 1.125 (aslında 1 + 0 + 0 + 0.125)
    1010 0000 0000 0000 0000 000 = 1.625 (aslında 1 + 0.5 + 0 + 0.125)
    0110 0000 0000 0000 0000 000 = 1.375
    1110 0000 0000 0000 0000 000 = 1.875
    0001 0000 0000 0000 0000 000 = 1.0625
    1001 0000 0000 0000 0000 000 = 1.5625 (Aslında 1 + 0.5 + 0 + 0 + 0.625 )
    0101 0000 0000 0000 0000 000 = 1.3125
    0011 0000 0000 0000 0000 000 = 1.1875
    1011 0000 0000 0000 0000 000 = 1.6875 ( aslında 1 + 0.5 + 0 + 0.125 + 0.625)
    0111 0000 0000 0000 0000 000 = 1.4375

    Sanırım seri anlaşılıyor ve aradığımız sayıya ulaştık.

    Eh mantissayı da bulduk demek ki 23 sayısı aşağıdaki şekilde yazılabilirmiş:

    (23)10 = (0 1000 0011 0111 0000 0000 0000 0000 000) 2

    Sıra geldi virgülden sonraki kısmı hesaplamaya. Şimdi soruyu baştan soralım. Sorumuz 23 değil de 23.15'i bulmak olsaydı nasıl hesaplayacaktık? Öncelikle yön biti değişmiyor sayı yine pozitif. Üst biti değişmiyor çünkü sayı hala 16 ile 32 arasında ve biz üstümüzü 4 olarak alacağız. Sadece mantissa değişecek.

    Baştaki denkleme dönüyoruz ve 23 yerine 23.15 için aşağıdaki soruyu soruyoruz:

    23.15 = 24 * x
    yani 23.15 = 16x denklemindeki x'i bulacağız.

    Hesap makinemiz ile bölünce 1.446875 buluyoruz. Şimdi bu sayının mantissa gösterimine ihtiyacımız var. Aslında yapacağımız işlem basit. Aynı tam sayı kısmında 2 üzeri kaç ile kaç arasında gibi arama yaptığımız gibi şimdi ondalıklı sayı kısmına bakacağız. Yukarıda verdiğim ondalıklı sayı tablosunu hatırlayın, hani mantissa kısmı 23 tane sıfır ile başlayan ve adım adım arttırdığım 1.5, 1.25 şeklinde giden seri. Şimdi bizim sayımız. 1.446875 ise bu sayı hangi değerler arasında diye baktığımızda daha önce bulduğumuz 1.4375 bu sayıya oldukça yakın. Buradan başlayarak devam edersek

    0111 0000 0000 0000 0000 000 = 1.4375

    ve saymaya devam edersek aşağıdaki sayıya ulaştığımızda durabiliriz:

    0111 0010 0110 0110 0110 011 = 1.446874976158142

    Demek ki çözüm için aşağıdaki sayıdır denilebilir:

    (23.15)10 = (0 1000 0011 0111 0010 0110 0110 0110 011) 2

  21. hasan

    s.a hocam şu sorumu cevaplarsanız sevinirim
    1 11001010 1000100 00000000 00000000 ikilik ve onluk sistemdeki değerleri

  22. hatip

    hocam anlattığınız konuda kafamda bir soru işareti kaldı tabloda

    0 10000011 01010100000000000000000 şeklide göstermişsiniz yalnız sayı kısmını yazarken sıfırları sağına eklemişsiniz bu sayımızın değerinin değişmesine sebep olmazmı mesela sayı 101 iken biz 10100 şeklinde yazıyoruz sayının geri dönüşümünü yaparken elimizde 101 olmadığından biz 10100 sayısını çeviririz buda 5 sayısını 20 olarak çevirmemize neden olur cevap verebilirseniz çok sevinirim

  23. Eda

    Hocam merhaba ben birinci sınıf öğrencisiyim de girilen sayinin basamak değerlerini nasıl bulacağımı bilmiyorum yardim edermisiniz

  24. Furkan

    2125 sayısını 10 luk tabandan 2lik tabana cevirirken yanlıslık var.
    21,25 sayısının eşitliklerinde 2,125 10^1 olacak -1 değil

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


× 1 = iki