Akademisyenler öncülüğünde matematik/fizik/bilgisayar bilimleri soru cevap platformu
1 beğenilme 0 beğenilmeme
48 kez görüntülendi
Bilgisayar 0'lar ve 1'ler ile çalışır denir sürekli. Bir tamsayı ya da bir reel sayı bilgisayarın işlemcisinde ve belleğinde nasıl temsil edilir?
Uygulamalı Bilgisayar Bilimi kategorisinde (227 puan) tarafından  | 48 kez görüntülendi

2 Cevaplar

1 beğenilme 0 beğenilmeme

Bu soruyu yanıtlamak için önce ikili sayma sisteminden bahsetmek gerek. Artık nedense ilköğretim müfredatından kaldırılmış, bilmeyenler olabilir. Günlük hayatımızda kullandığımız onlu sayma sisteminde 0'dan 9'a kadar 10 tane rakam vardır. Bir tamsayı yazdığınızda, sağdan sola doğru sayının basamaklarına birler basamağı, onlar basamağı, yüzler basamağı, vs. denir, yani 10'un kuvvetleri kullanılır. İlkokulda "çözümleme" adı altında, bir sayıyı şöyle yazmayı öğrenmiştik:

$$9604=9\times 10^3+6\times 10^2+0\times 10^1+4\times 10^0$$

İkili sayma sisteminde ise iki tane rakam vardır , 0 ve 1. Yazdığınız bir sayının basamakları da, yine sağdan sola, birler basamağı, ikiler basamağı, dörtler basamağı, sekizler basamağı vs. diye devam eder. Yani 2'nin kuvvetleri kullanılır. Örneğin,

$$1001101=1\times 2^6+0\times 2^5+0\times 2^4+1\times 2^3+1\times 2^2+0\times 2^1+1\times 2^0$$

Yukarıda 2'nin kuvvetlerini onlu sayma sisteminde hesaplayıp toplarsanız 77 çıkar. Yani bu sayı onlu sayma sisteminde 77'ye eşittir.

Şimdi bilgisayarda sayıların nasıl temsil edildiğinden bahsedelim. Burada anlatacaklarım, C ve türevi programlama dillerinin sayıları nasıl yorumladığı ile ilgilidir. Arduino gibi gömülü sistemler de sayıları burada anlatacağım gibi bellekte tutar ve yorumlar. Python'da falan bu durum değişik olabilir.

İkili sayma sisteminde gösterilen sayılarda her basamağa bir "bit" denir. "Binary digit"in kısaltması. Bir bit, 0 ya da 1 değerini alabilir. 8 bit'e, 1 Byte denir. Bellek için bahsediyorsak 1024 Byte'a 1 kiloByte  (kB), 1024 kiloByte'a 1 MegaByte (MB), 1024 MegaByte'a 1 GigaByte (GB) denir. Sabit diskler için bu ölçü farklı olabilir, ama biz bellekten bahsediyoruz. Mesela bilgisayarınızın 4 GB RAM'i varsa,

$$4\times 1024\times 1024\times 1024 \times 8=2^{35}$$

kadar bit'ten oluşuyor demektir. Yani ikili sayma sisteminde yazılmış $2^{35}$ basamaklı bir sayıyı bellekte tutabilirsiniz, her basamakta ya 0 ya 1 olabilir. Daha fazlasını tutamazsınız. 

Günümüzdeki bilgisayarlarda bir tamsayı (integer), bellekte 4 byte (yani 32 bit) yer tutar. C'de, örneğin,

int a=77;

yazdığınızda, "a" değişkeni için bellekte 32 bit'lik bir yer ayrılır, ve bu yere şu 32 basamaklı sayı yazılır:

$$00000000000000000000000001001101$$

Bu sayının onlu sistemde 77'ye eşit olduğunu yukarıda söylemiştik. Eskiden (80'lerde) Commodore 64 vardı, orada genellikle 8 bit tamsayılar kullanılırdı ve bu herkese yeterdi. Yani orada 77 sayısı, $01001101$ diye 8 bit (yani 1 byte) bir sayı olarak gösterilirdi. 8 bit ile gösterebileceğiniz en büyük sayı 255'tir. 32 bit ile, en fazla $2^{32}-1=4.294.967.295$ sayısını gösterebilirsiniz. Daha büyük bir sayıyı gösteremezsiniz. Eğer programınızda kullandığınız tamsayı değişkenin alacağı değer bu seviyelere ulaşmıyorsa, bellekte boşa 4 byte'lık yer israfı yapıyorsunuz demektir. 4 GB belleği olan bir PC için pek sorun değil belki bu ama, hepi topu 32 kB belleği olan Arduino Uno gibi bir bilgisayarda program yazıyorsanız, israf yapmak istemezsiniz. O yüzden mesela Arduino'da "short" diye bir veri tipi vardır. 2 byte (yani 16 bit) yer tutan integer değişkenini simgeler. Bu tip bir değişken en fazla $2^{16}-1=65535$ değerini alabilir. Eğer 32 bit size yetmiyorsa, 64 bit yer tutan integer değişkenler de vardır.

Bu noktada, bilgisayardaki sayılar ile matematikteki sayıların temel bir farkı olduğunu gördük. Matematikte en büyük tamsayı yoktur, ama bilgisayarda en büyük tamsayı olmak zorundadır. Çünkü bilgisayarın belleği sonludur.

Negatif tamsayılardan ve virgüllü sayılardan daha bahsetmedik. Yakında bu cevabı güncelleyip onlardan da bahsedeceğim.

**Güncelleme

Negatif tamsayılar

Bellekte artı ve eksi kavramları olmadığından, sayının işareti için de bit'leri kullanmak zorundayız. Eğer negatif sayıları da işin içine katıyorsak, sayının en soldaki bit'i (buna most significant bit denir) sayının işaretini gösterir. 0 ise sayı pozitiftir, 1 ise negatiftir. Negatif tamsayıları temsil etmek için farklı yöntemler uygulanabilir, ama standardı two's complement (ikiye tamamlama) yöntemidir. Basit olsun diye 8 bit'lik bir bilgisayar olduğunu varsayalım, ve $-1$ sayısının gösterimini bulalım. Öyle bir sayı bulacağız ki, 1 ekleyince cevap 0 olmalı. Yani ikili sistemde 8 bit sayılarla yazmak gerekirse, $-1$'e $00000001$ ekleyince, $00000000$ bulmalıyız. Buradan görülür ki, bilgisayarda $-1$ sayısı, $11111111$ olarak temsil edilir. Sayı işaretli ise, $11111111$ sayısı $-1$ olarak yorumlanır. Sayı işaretsiz ise, $11111111$ sayısı $255$ olarak yorumlanır. Bu yorumlamayı da programcı olarak siz yapabilirsiniz, ya da genellikle programı yazdığınız compiler bu işi halleder. Herhangi bir sayının eksilisini bulmak için, bit'leri ters çevirip 1 eklenir. Örneğin 77 sayısını 8 bit olarak $01001101$ olarak yazmıştık. -77 sayısı için bit'ler ters çevrilip 1 eklenir, yani $10110011$ olarak yazılır. Aynı işlemi -77'ye yaparsanız, +77 bulursunuz. Bunun neden böyle olduğu çok basit, açıklamayacağım. Dikkat ederseniz, $00000000$'ın negatifi kendisine eşittir.

Yine 8 bit için, sayılarınız işaretsiz ise, yani negatif sayılar ile hiç işlem yapmayacaksanız, 0'dan 255'e kadar olan sayıları temsil edebilirsiniz. Ama negatif sayılar ile de işlem yapacaksanız, temsil edebileceğiniz pozitif sayılar 0 ile 127 arasındadır (en sol biti 0 olanlar). Negatif sayılar da -1 ile -127 arasındadır (en sol biti 1 olanlar). Ama negatifi kendisine eşit bir tane daha sayı kaldı, $10000000$ sayısını ne yapacağız? Konvansiyonel olarak bu sayı -128 olarak yorumlanır. Yani 8 bit ile, -128 ile 127 arası tamsayıları temsil edebilirsiniz. Benzer şekilde, 16 bit ile de -32768 ile 32767 arasındaki sayılar temsil edilebilir.

Virgüllü sayılar

Irrasyonel sayılar ve devirli rasyonel sayılar virgülden sonra sonsuz basamağa sahip olduklarından, ama bilgisayarın belleği sonlu olduğundan, bilgisayarda hatasız temsil edilemezler. Bir yerde durmak gerekir. Bu tip sayılara ingilizcede floating point denir. Türkçeye kayan nokta olarak da çeviriliyor ama, bildiğimiz virgüllü sayı aslında. Günümüzde artık yaygın olarak double precision floating point sayılar kullanılıyor. Bunlar 64 bit (yani 8 byte) yer kaplar, ve şu formattadır:

Bu sayıya $X$ diyelim. En soldaki bit işaret bitidir, 0 ise sayı pozitif, 1 ise negatiftir. Sonraki 11 bit Exponent yani üs, sonraki 52 bit ise Fraction yani kesiri gösterir. Son 52 bit'e yaygınlıkla Mantis de denir. $E$, 11 bit ve işaretsiz bir tamsayıdır, yani 0 ile 2047 arasında değer alır. Bu 64 bit'lik sayı, $1\leq E\leq 2046$ için şuna eşittir:

$$X=(-1)^S\times 1.F\times 2^{E-1023}$$

$E=0$ veya $E=2047$ de olabilir ama bunlar özel durumlardır, burada konu etmeyelim.

Örneğin, bu formatta yazabileceğiniz en büyük sayı, $S=0$, (yani $+$), $E=2046$, $F=111\ldots 1$ (52 tane) değerlerine karşılık gelir. Bu sayı yaklaşık $2^{1024}\approx 10^{308}$ civarındadır. Bu formatta temsil edebileceğiniz en büyük sayı budur.

Bizim için daha önemli olacak soru şu: bu sayıların hassasiyeti ne kadardır? Örneğin $X=1$'e bakalım. $1.000\ldots 0\times 2^0$ diye yazacağız. Yani $F=000\ldots 0$ ve $E=1023$.

Şimdi, $X=1$'den büyük olan en küçük sayıyı düşünelim. Matematikte böyle birşey yok ama bilgisayarda var. Bu sayı, $X=1.000\ldots001\times 2^0$ sayısıdır. Yani $E=1023$ ve $F=000\ldots 01$'e karşılık gelir. Bu sayı ile 1 arasındaki fark, ikili sistemde $0.000\ldots 01$ sayısıdır. Virgülden sonra 52. basamakta 1 olduğundan, bu sayı $2^{-52}$'ye eşittir, ve bu sayı formatının hassasiyetini verir. Numerik hesaplama alanında, bu sayıya machine epsilon denir.

Virgülden sonra sonsuz basamağı olan sayıları 52. basamakta kestiğinizde bu civarda bir hata yaparsınız. Bu formatta daha küçük bir hassasiyet elde etmek mümkün değildir. Onlu sistemde $2^{-52}\approx 2.22\times 10^{-16}$ olduğundan, bu tip double precision sayılarla yaptığınız işlemlerde bulduğunuz sonuç, virgülden sonraki 16. basamaktan sonra güvenilirliğini kaybeder. 

(227 puan) tarafından 
tarafından düzenlendi
Pek tam olmayan sayıları nasıl temsil ediyor, onu da yazar mısın?
1 beğenilme 0 beğenilmeme

kerem.altun sayilarin klasik bilgisayar programlarinda nasil ifade edebilecegimizin cevabini cok guzel vermis

Yazilimda bu tur sinirli sayilari dinamik data bicimleriyle birlikte kullanip bilgisayarin hafizasinin izin verdigi olcude buyuk dogal sayilar yazmak mumkun. Dogal sayilari ifade ettikten sonra tam sayilari ifade etmek icin dogal sayilara bir bit ekleyerek negatiflik veya pozitiflikten bahsedebiiliriz. Iki tamsayi kullanarak bir rasyonel sayi yazabiliriz ve iki rasyonel sayi kullanarak ise bazi reel sayilara istedigimiz kadar yaklasabiliriz. Araliklar aritmetigi (interval arithmetics) deniliyor galiba bu sisteme.


Ilginc bir soru ise elimizde gercekten bir Turing makinasi olsa  hangi sayilari gosterebilirdik?

Her reel sayiyi ifade edemeyecegimizi biraz el sallayarak su sekilde gosterebiliriz :

  • Reel sayilar sayilamaz sonsuz buyuk,
  • Sayilabilir sonsuz tane turing makinasi var,
  • Bunlarin arasinda birebir ve orten bir fonksiyon olamaz.


Ama bazi reel sayilari "gosterebilecegimizi" biliyoruz.

Misal $\pi$, $e$.

Bu sayilara istediginiz kadar yakinsayan programlar yazabilirsiniz. Dahasi bu programlar uzerinde aritmetik operasyonlar yapabilirsiniz ama maalasef bu sayilarin esit oldugunu gostermek bir turing makinasinin durup durmayacagina denk. Bu sayilara hesaplanabilir sayilar (computable numbers ) diyelim.

Aritmetik operasyonlarin hesaplanabilir sayilarda kapaliligi bu kumeyi bir cisim yapar.

Kendim kullanmadim ama bildigim kadariyla RealLib adli kutuphane hesaplanabilen reel sayilar kullanmaya olanak sagliyor

(411 puan) tarafından 
tarafından düzenlendi
18,541 soru
20,842 cevap
67,815 yorum
19,255 kullanıcı