{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# AST416 Astronomide Sayısal Çözümleme - II #\n",
"## Ders - 02a Bilgisayarda Sayıların Temsili ve Yuvarlama Problemleri ile Python Çözümleri ##"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Doç. Dr. Özgür Baştürk
\n",
"Ankara Üniversitesi, Astronomi ve Uzay Bilimleri Bölümü
\n",
"obasturk at ankara.edu.tr
\n",
"http://ozgur.astrotux.org"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Bu derste neler öğreneceksiniz?#\n",
"## Bilgisayarda Sayıların Temsili ve Yuvarlama Problemleri ile Python Çözümleri ##\n",
"\n",
"* [Yuvarlama Yanlışları](#Yuvarlama-Yanlışları)\n",
"* [Kayan Noktalı Sayılar](#Kayan-Noktalı-Sayılar)\n",
"* [Sayı Sistemlerindeki Temsil Sorunları](#Sayı-Sistemlerindeki-Temsil-Sorunları)\n",
"* [Kesme ve Yuvarlama İşlemleri](#Kesme-ve-Yuvarlama-İşlemleri)\n",
" * [Makine Epsilonu](#Makine-Epsilonu)\n",
" * [ Aritmetik İşlemlerin Getirdiği Kesme ve Yuvarlama Yanlışları](#Aritmetik-İşlemlerin-Getirdiği-Kesme-ve-Yuvarlama-Yanlışları)\n",
" * [1 Toplama ve Çıkarma](#1-Toplama-ve-Çıkarma)\n",
" * [2 Çarpma ve Bölme](#2-Çarpma-ve-Bölme)\n",
" * [3 Büyük ve Küçük Sayıyla Toplama Çıkarma](#3-Büyük-ve-Küçük-Sayıyla-Toplama-Çıkarma)\n",
" * [4 Yakın İki Sayıyı Çıkarma](#4-Yakın-İki-Sayıyı-Çıkarma)\n",
"* [Python'da Kayan Noktalı Sayılar](#Python'da-Kayan-Noktalı-Sayılar)\n",
"* [Decimal Modülü](#Decimal-Modülü)\n",
" * [Decimal Modülünün Kullanımına Bazı Örnekler](#Decimal-Modülünün-Kullanımına-Bazı-Örnekler)\n",
" * [Decimal Modülünde Yuvarlama Seçenekleri](#Decimal-Modülünde-Yuvarlama-Seçenekleri)\n",
"* [Numpy Modülünde Yuvarlama Seçenekleri](#Numpy-Modülünde-Yuvarlama-Seçenekleri)\n",
"* [Pandas Modülünde Yuvarlama Seçenekleri](#Pandas-Modülünde-Yuvarlama-Seçenekleri)\n",
"* [Kaynaklar](#Kaynaklar)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Yuvarlama Yanlışları #\n",
"\n",
"Yuvarlama konusunun ayrıntlı olarak anlatıldığı [Hata Analizi](Ders01_Hata_Analizi_Uygulamalar.html) dersinde ayrıntılı olarak verildiği gibi Yuvarlama yanlışları temelde iki problemden kaynaklanır:\n",
"\n",
"1. $\\pi$, $e$, $\\sqrt{7}$ gibi sayılar sabit sayıda anlamlı rakamla temsil edilemezler. Bu nedenle bilgisayarlar da bu sayıları tam olarak temsil edemez. \n",
"\n",
"2. Bilgisayarlar ikilik sayı sistemini kullandıklarından onluk sayı sistemine dayalı tüm sayıları aynı duyarlılıkta temsll edemezler.\n",
"\n",
"Yuvarlama işlemi kaynaklı hatalar sayıların bilgisayarda tutulma şekline doğrudan bağlıdır. 10 parmağımız olduğu için onluk sayı sistemi biz insanlar için “doğal” olandır. Bir bilgisayar ise sadece 2 parmağı olan bir varlık gibi düşünülebilir. Bu nedenle ikilik sayı sistemi de onun için “doğal” olandır. \n",
"\n",
"Herhangi bir tamsayı onluk ve ikilik sayı sistemlerinde aşağıdaki şekillerde çözümlenir (Chapra & Canale 2009). "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image\n",
"Image(filename='images/sayi_sistemleri.png', width=400)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Bu durum her iki sayı sisteminde ve diğer tüm sayı sistemlerinde sayıların mükemmel temsil edilemiyor olmasına yol açar. Buna ek olarak bilgisayarlar sınırlı kapasiteleri nedeniyle sadece belirli bir sayı aralığını temsil edebilirler. Örneğin 16 bitlik bir sayı sistemi varsayılan olarak -32768 ile 32767 arasındaki tam sayıları saklayabilir. 16 bitlik CCD dedektörlerde algılanan fotonların ADU biriminden karşılığının 0-65535 arasında olbilmesinin nedeni de budur. Foton algılama işlemi doğası gereği bir \"sayım\" işlemi olduğundan negatif sayılara ihtiyaç duyulmaz."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image\n",
"Image(filename='images/sayi_sistemleri_16bit.png', width=400)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Yukarıdaki şekilde şematik olarak gördüğünüz 16 bit ikilik sayı sisteminde, her bir basamak sadece 0 veya 1 değerini alabilir ve toplamda 16 basamak vardır. 1. basamak işaret için ayrılır ve 0 iki kere sayılmaz. En baştaki 0: pozitif, 1: negatif sayıları ifade eder. Bu durumda yazılabilecek en küçük sayı $1111111111111111$ (bu sayının onluk sayı sistemindeki karşılığı -32767 olduğu halde 0'ı iki kez saymamak için onu pozitif sayılara dahil edip saymaya -1'den başladığımız için -32768) olurken en büyük sayı $0111111111111111$ (32767) olur. \n",
"\n",
"[Başa Dön](#Bu-derste-neler-öğreneceksiniz?)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Kayan Noktalı Sayılar #\n",
"\n",
"Bilgisayarlar tam sayılar dışındaki sayıları göstermek üzere \"kayan noktalı\" sayıları (ing. floating point numbers) kullanırlar. Aşağıda kayan noktaları sayıların hafızada saklanma şeklini örnekleyen bir şekil bulunmaktadır. Herhangi bir sayı bu şekilde m: mantis, b: taban, e: üssü göstermek üzere\n",
"\n",
"$$ m~b^e $$\n",
"\n",
"şeklinde ifade edilir."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image\n",
"Image(filename='images/sayi_sistemleri_floatingpoint.png', width=400)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Örneğin onluk sayı sistemindeki $156.78$ sayısını düşünelim. Bu sayıyı bilimsel gösterimde (ing. scientific notation) şu şekilde ifade edebiliriz: $0.15678 x 10^{3}$.\n",
"\n",
"Eğer mantis başında gereksiz $0$ sayıları varsa normalize edilebilir. Örneğin, $1 / 34 = 0.029411765...$ sadece 4 basamağa izin verilen 10'luk bir kayan sayı sisteminde $0.0294 x 10^0$ şeklinde saklanabilir. Ancak bu şekilde noktadan sonraki 0 nedeniyle 5. basamaktaki $1$ sayısını kaybetmiş oluruz. Bunu sayıyı $0.2941 x 10^{-1}$ şeklinde göstererek aşabiliriz. Noktanın bu şekilde kaydırılması bu sayıların \"kayan noktalı sayılar” (ing. floating point numbers) olarak adlandırılmış olmasının da kaynağıdır. Böylece noktadan sonra gelen gereksiz 0'a da izin verilmemiş olur. Bu işleme normalizasyon adı verilir ve sayılarda anlamsız rakamların elenmesi işlevini de görür.\n",
"\n",
"Normalizasyonun doğal bir sonucu mantis (m) için limitli bir değer aralığına sahip olunmasıdır. b, tabanı; m, mantisi göstermek üzere\n",
"\n",
"$$\\frac{1}{b} \\le m \\lt 1$$\n",
"\n",
"Örneğin onluk sayı sisteminde \n",
"\n",
"$$0.1 \\le m \\lt 1$$ iken ikilik sayı sisteminde \n",
"\n",
"$$ 0.5 \\le m \\lt 1$$ "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Örnek: Yedi bitlik ikilik bir sayı sistemini ele alalım (Şekil Chapra & Canale 2009'dan alınmış ve Türkçeleştirilmiştir) ve bu sayı sisteminde ifade edilebilecek en büyük ve en küçük sayıları hesaplamak istiyor olalım."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image\n",
"Image(filename='images/sayi_sistemleri_7bit.png', width=300)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Bu sistemde ifade edebileceğimiz en küçük poziftif sayı $011100$ 'dir. bu sayının onluk sayı sistemindeki karşılığı $m = 1x2^{-1} + 0x2^{-2} + 0x2^{-3} = 0.5$, $b=2$ , $e = -(1x2^0 + 1x2^1) = -3$ olduğundan \n",
"\n",
"$$ (1x2^{-1} + 0x2^{-2} + 0x2^{-3}) x 2^{-(1x2^1+1x2^0)} = 0.5 x 2^{-3} = 0.0675 $$\n",
"\n",
"sayısıdır. \n",
"\n",
"En büyük poziftif sayı ise $0011111$ sayısı olup onluk sayı sistemindeki karşılığı $m = 1x2^{-1} + 1x2^{-2} + 1x2^{-3} = 0.875$, $b=2$ , $e = 1x2^0 + 1x2^1 = 3$ olduğundan \n",
"\n",
"$$ 1x2^{-1} + 1x2^{-2} + 1x2^{-3}) x 2^{1x2^1 + 1x2^0} = 0.875 x 2^{3} = 7 $$\n",
"\n",
"sayısıdır.\n",
"\n",
"Aslında bu sayı sisteminde daha küçük mantisler yazabiliriz ($000$, $001$, $010$, $011$) ancak normalizsyon gereği noktadan sonraki gereksiz $0$'ları atmaya yönelik bir işlem uygulanacağından buna izin verilmez. Dolayısı ile en küçük olarak ifade edilebilien bu sayıyı aşağıdaki sayılar takip eder:\n",
"\n",
"$$ 0111101 = (1 x 2^{−1} + 0 x 2^{−2} + 1x2^{−3}) x 2^{−3} = (0.078125)_{10} $$\n",
"$$ 0111101 = (1 x 2^{−1} + 1 x 2^{−2} + 0x2^{−3}) x 2^{−3} = (0.093750)_{10} $$\t\n",
"$$ 0111101 = (1 x 2^{−1} + 1 x 2^{−2} + 1x2^{−3}) x 2^{−3} = (0.109375)_{10} $$\t\n",
"\n",
"Bu sayı sistemiyle $0.0675$ sayısından küçük pozitif sayıların temsil edilememesinin yanı sıra her sayının da temsil edilemediğine dikkat ediniz. Sayılar $0.015625$ aralıkla artmakta, bu artışın altındaki artışlarla ulaşılacak sayılar gösterilememektedir! Bu noktadan sonra sayıyı büyütmek için üssü büyütmeliyiz!\n",
"\n",
"$$ 0110100 = (1 x 2^{−1} + 0 x 2^{−2} + 0x2^{−3}) x 2^{−2} (0.125000)_{10} $$\n",
"$$ 0110101 = (1 x 2^{−1} + 0 x 2^{−2} + 1x2^{−3}) x 2^{−2} = (0.156250)_{10} $$\n",
"