{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Darstellung von Zahlen"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Summe von Potenzen einer Basis\n",
    "\n",
    "$x = c_0 \\cdot b^0 + c_1 \\cdot b^1 + \\dots + c_n \\cdot b^n$\n",
    "\n",
    "-----\n",
    "\n",
    "Beispiele: $128$ und $11,57$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "$128_{10} = 1 \\cdot 10^2 + 2 \\cdot 10^1 + 8 \\cdot 10^0$ \n",
    "\n",
    ">$= 1 \\cdot 2^7 + 0 \\cdot 2^6 + \\ldots + 0 \\cdot 2^0$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "$11,57_{10} = 1 \\cdot 10^1 + 1 \\cdot 10^0 + 5 \\cdot 10^{-1} + 7 \\cdot 10^{-2}$\n",
    "\n",
    ">$= 1 \\cdot 2^3 + 0 \\cdot 2^2 + 1 \\cdot 2^1 + 1 \\cdot 2^0 + 1 \\cdot 2^{-1} +...$\n",
    "\n",
    ">$=8 + 0 + 2 + 1 + 0.5 + \\ldots$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Zahlen in Python\n",
    "\n",
    "Python numeric built-in types: \n",
    "* int\n",
    "* float\n",
    "* complex\n",
    "\n",
    "https://docs.python.org/3.4/library/stdtypes.html#numeric-types-int-float-complex\n",
    "\n",
    "NumPy: \n",
    "* int \\<x>\n",
    "* uint \\<x>\n",
    "* float \\<x>\n",
    "* complex \\<x>\n",
    "\n",
    "https://numpy.org/devdocs/user/basics.types.html\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        14:\t<class 'int'>\n",
      "    2.3792:\t<class 'float'>\n",
      "    (3+7j):\t<class 'complex'>\n",
      "       -11:\t<class 'numpy.int32'>\n",
      "         5:\t<class 'numpy.uint32'>\n",
      "      8.23:\t<class 'numpy.float64'>\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "numbers = [14, 2.3792, 3+7j, \n",
    "           np.int32(-11), np.uint32(5), np.float64(8.23)]\n",
    "for num in numbers:\n",
    "    print(\"{:10}:\\t{}\".format(num, type(num)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "### Beispiele \n",
    "\n",
    "* $\\sqrt{2} \\cdot \\sqrt{2} \\stackrel{?}{=} 2$\n",
    "\n",
    "* $\\sin(\\pi) \\stackrel{?}{=} 0$\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "x = np.sqrt(2)\n",
    "print(x*x == 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = 1.4142135623730951\n",
      "x*x = 2.0000000000000004\n"
     ]
    }
   ],
   "source": [
    "print(\"x = {}\".format(x))\n",
    "print(\"x*x = {}\".format(x*x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "y = np.sin(np.pi)\n",
    "print(y == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y = 1.2246467991473532e-16\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(\"y = {}\".format(y))\n",
    "print(np.isclose(y,0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Gleitkommazahlen\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Motivation\n",
    "\n",
    "Festkommazahl: $x = \\pm m_1 m_2 \\dots m_n \\cdot 10^e$ für feste $n$ und $e$\n",
    "\n",
    "z.B. mit $n = 3$ und $e = -2$\n",
    "\n",
    "* $0,01 = 1 \\cdot 10^{-2}$\n",
    "* $3,47 = 347 \\cdot 10^{-2}$\n",
    "* $9,99 = 999 \\cdot 10^{-2}$\n",
    "\n",
    "Darstellbare Zahlen haben gleichen Abstand aber Zahlenbereich eingeschränkt auf [0,00 - 9,99]."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "Gleitkommazahl: $x = \\pm m_1, m_2 \\dots m_n \\cdot 10^e$ für feste $n$ und \"beliebige\" $e$\n",
    "\n",
    "* $0,001 = 1 \\cdot 10^{-3}$\n",
    "* $0,105 = 105 \\cdot 10^{-3}$\n",
    "* $3,47 = 347 \\cdot 10^{-2}$\n",
    "* $105.000 = 105 \\cdot 10^{3}$\n",
    "\n",
    "Praktisch uneingeschränkter Zahlenbereich... Abstand zwischen darstellbaren Zahlen aber __nicht__ gleich. \n",
    "\n",
    "z.B. $106.000 - 105.000 = 1.000 \\neq 0,001 = 0,106 - 0,105$\n",
    "\n",
    "Kompromiss zwischen Umfang und Genauigkeit. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "<img src=\"imgs/GKZ_Strahl.png\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Definition\n",
    "\n",
    "$\\hat{x} = \\pm m_1, m_2 \\dots m_n \\times b^{e_1\\dots e_k} \\in \\mathbb{G}(b, n)$\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "IEEE 754 bestimmt $b$, $n$ und $k$:\n",
    "\n",
    "* 32bit float: 1bit Vorzeichen, 8bit Exponent (k), 23bit Mantisse (n).\n",
    "* 64bit float: 1bit Vorzeichen, 11bit Exponent (k), 52bit Mantisse (n).\n",
    "* Basis ist typischerweise 2. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-3.4028235e+38 3.4028235e+38\n",
      "-1.7976931348623157e+308 1.7976931348623157e+308\n"
     ]
    }
   ],
   "source": [
    "# Smallest and largest fp number\n",
    "print(np.finfo(np.float32).min, np.finfo(np.float32).max)\n",
    "print(np.finfo(np.float64).min, np.finfo(np.float64).max)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.1754944e-38\n",
      "2.2250738585072014e-308\n"
     ]
    }
   ],
   "source": [
    "# Absolute smallest fp number\n",
    "print(np.finfo(np.float32).tiny)\n",
    "print(np.finfo(np.float64).tiny)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8388611\n",
      "8388611.0\n"
     ]
    }
   ],
   "source": [
    "x = 2**23\n",
    "y = np.float32(x+3)\n",
    "print(x+3)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "$G: \\mathbb{R} \\rightarrow \\mathbb{G}: rd(x) = \\hat{x}$\n",
    "\n",
    "$E_{rd}(x) = \\left|x - \\hat{x}\\right| = \\left|x-rd(x)\\right|$}\n",
    "\n",
    "Im Allgemeinen wird zum nächsten Wert gerundet. Der Fehler ist also maximal, wenn $x$ in der Mitte zweier benachbarten Gleitkommazahlen liegt. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "<img src=\"imgs/G_fkt.jpg\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Abstand zwischen zwei Gleitkommazahlen\n",
    "\n",
    "$m_1, m_2 \\dots m_n + 1 \\times b^e - m_1, m_2 \\dots m_n \\times b^e = 0, 0 \\dots 1 \\times b^e$\n",
    "\n",
    "> $\\Delta\\mathbb{G} = 1,0 \\dots 0 \\times b^{e - (n-1)}$\n",
    "\n",
    "Der Abstand ist nicht konstant, sondern abhängig von der Größe der Zahlen. Dies ist beabsichtigt, damit der relative Fehler konstant bleibt."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "<img src=\"imgs/Exakt_darstellbare_Gleitkommazahlen.png\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Absoluter vs. relativer Fehler\n",
    "\n",
    "Absoluter Fehler: $E_a = |x_a - x|$ \n",
    "\n",
    "z.B. \n",
    "\n",
    "* $1 + 1 = 3,\\quad E_a = \\left| 3 - 2 \\right| = 1$\n",
    "\n",
    "\n",
    "* $10000 + 10000 = 200001,\\quad E_a = \\left|20001 - 20000\\right| = 1$\n",
    "           "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "\n",
    "Relativer Fehler: $E_r = \\frac{E_a}{|x|} = \\frac{|x_a - x|}{|x|}$\n",
    "\n",
    "$E_r = \\frac{| 3 - 2 |}{2} = 0,5, \\quad E_r = \\frac{|20001 - 20000|}{20000} = 0,000005$\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "Relativer Fehler zwischen zwei benachbarten Gleitkommazahlen.\n",
    "\n",
    "z. B. \n",
    "\n",
    "$E_r = \\frac{|106.000-105.500|}{105.500} = \\frac{500}{105.000} =~ 0,0048$\n",
    "\n",
    "$E_r = \\frac{|0,106 - 0,1055|}{0,1055} = \\frac{0,0005}{0,1055} =~ 0,0047$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Maschinengenauigkeit\n",
    "\n",
    "* maximaler relativer Approximationsfehler bei Verwendung der Gleitkommazahlen $\\mathbb{G}(b,n_m)$ \n",
    "\n",
    " $$\\epsilon = \\underset{x \\in \\mathbb{Q}^+}{\\text{max}} \\frac{x-G(x)}{x} \\leq \\frac{b^{e-n_m+1}}{b^e} = b^{-n_m+1}$$\n",
    " \n",
    "* alternative Definition \n",
    "\n",
    "$$\\epsilon = \\underset{x \\in \\mathbb{Q}}{\\text{arg min}} \\ G(1+x) > 1$$\n",
    "\n",
    "* Maschinengenauigkeit: $\\epsilon = b^{-n_m+1}$ \n",
    "    - Basis\n",
    "    - Mantissenlänge "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Genauigkeit bei Elementaroperationen\n",
    "\n",
    "* Gleitkommazahlen $\\mathbb{G}$ gegenüber    $ \\ +, \\ $  $ -, \\ $  $\\cdot, \\ $  $ / \\ $   **nicht abgeschlossen**\n",
    "\n",
    "![](figures/zahlenstrahl2.png)\n",
    "\n",
    "$$ x \\ast y \\neq G(x \\ast y) \\neq G(x) \\ast G(y) \\neq G(G(x) \\ast G(y))$$\n",
    "\n",
    "\n",
    "* $G(G(x) \\ast G(y))$ entspricht dem, was Computer berechnet\n",
    "\n",
    "\n",
    "* Relativer Fehler für $ \\ +, \\ $  $\\cdot, \\ $  $/, \\ $ in Größenordnung von Maschinengenauigkeit $\\epsilon$\n",
    "\n",
    "* Relativer Fehler für $ \\ - \\ $ unbegrenzt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Auslöschung...\n",
    "* ... führender Stellen, Darstellung des Ergebnisses nur mit kleinem Teil der Mantisse\n",
    "\n",
    "\n",
    "* Bei Subtraktion kann **relativer Fehler beliebig groß** werden\n",
    "\n",
    "\n",
    "* Tritt auf bei Bildung der **Differenz zweier ähnlich großer Zahlen** \n",
    "\n",
    "**Achtung:** auch Addition einer positiven und einer negativen Zahl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}