{ "cells": [ { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "remove_cell" ] }, "source": [ "
\n", "
\n", "

Ingenieurinformatik – Übung

\n", " Lehrstuhl Computational Civil Engineering
\n", " Kontakt: Email senden | Individuelle Kontakte siehe Webseite des Lehrstuhls
\n", " Links: \n", " Vorlesungsskript | \n", " Webseite des Lehrstuhls\n", "
\n", "
\n", " \n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Zahlendarstellung" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "In dieser Aufgabe wird die digitale Darstellung von ganzen und reellen Zahlen vertieft. Insbesondere soll die Umwandlung von reellen Zahlen in Gleitkommazahlen verdeutlicht und die Grenzen der digitalen Darstellung illustriert werden." ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Grundlagen und Beispiele" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "### Ganze Zahlen\n", "Die Umwandlung ganzer Zahlen erfolt direkt über die Zahlendarstellung im Dualsystem. Soll ein Vorzeichen dargestellt werden, so wird dieses im höchsten Bit gespeichert. Hierbei wird oft die Zahl als negativ interpretiert, wenn das höchste Bit einen Wert von Eins hat. " ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "### Gleitkommazahlen\n", "\n", "Die Darstellung von Gleitkommzahlen in binären Systemen kann auf unterschiedliche Weisen erfolgen. Die mit Abstand weitverbreiteste Methode wird im IEEE754 Standard beschrieben. Die hier verwendeten Beispiele folgen dem Verfahren dieses Standards und werden im folgenden kurz vorgestellt." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Für einen besseren Überblick und eine kürzere Schreibweise wird in diesem Beispiel eine hypothetische 8-Bit-Darstellung verwendet. Die real eingesetzten Verfahren für höhere Bitwerte, typischerweise 32 und 64 Bit, sind gleich. Eine mögliche Aufteilung der Bits könnte wie in folgender Abbildung aussehen." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| ![float8](zahlendarstellung_float8.png) |\n", "| :--: |\n", "| Bild: Hypothetische Bitaufteilung einer 8-Bit Darstellung einer Gleitkommazahl |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In diesem Beispiel wird eine Gleitkommazahl $a$ wie folgt durch das Vorzeichen $s$, die Mantisse $m$ umd den Exponenten $e$ abgebildet:\n", "$a = (-1)^{s} \\cdot (1.0+m) \\cdot 2^{e-3}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Zur Umwandlung von der binären Darstellung in eine Gleitkommazahl sind folgende Schritte notwendig. Diese werden anhand der Bitfolge 110110112 verdeutlicht." ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "#### Schritt 0\n", "Zur besseren visuellen Darstellung werden die Bitgruppen getrennt nach obiger Aufteilung dargestellt:\n", "\n", "110110112 = 1 101 10112" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Schritt 1\n", "Bestimmen Sie das Vorzeichen der Gleitkommazahl \n", " - Vorzeichenbit = 1 : die Gleitkommazahl ist negativ \n", " - Vorzeichenbit = 0 : die Gleitkommazahl ist positiv \n", " \n", "In unserem Beispiel ist die Gleitkommazahl negativ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Schritt 2\n", "Berechnen Sie den Exponenten $e$ indem Sie die binäre Zahl in das Dezimalsystem umwandeln. Hierbei wird eine vorzeichenlose ganze Zahl angenommen. \n", "\n", "In unserem Beispiel ergibt sich somit\n", " $e$ = 1012 = 510" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Schritt 3\n", "Als letztes muss noch die Mantisse bestimmt werden. Da durch die Mantisse keine ganze Zahl dargestellt werden soll, ist hier die Umwandlung etwas komplexer. \n", "\n", "Um eine – in diesem Zahlenformat definierte – Umrechnung zu demonstrieren werden die Bits der Mantisse durchnummeriert. Von links nach rechts gehend, sind die einzelnen n-Bits der Mantisse wie folgt gekennzeichnet: $m_1$, $\\dots$, $m_n$. In unserem Beispiel ist $n=4$ und \n", "\n", "* Bits der Mantisse: 10112\n", "* $m_1 = 1$\n", "* $m_2 = 0$\n", "* $m_3 = 1$\n", "* $m_4 = 1$\n", "\n", "Der Formatdefinition wird der Wert der Mantisse $m$ mit folgender Vorschrift berechnet:\n", "\n", "$$ m = \\sum_{i=1}^n \\frac{m_i}{2^i} $$\n", "\n", "Und somit ergibt sich folgender Wert für $m$ in unserem Beispiel:\n", "\n", "$$ m = \\frac{1}{2^1} + \\frac{0}{2^2} + \\frac{1}{2^3} + \\frac{1}{2^4} = \\frac{11}{2^4} = \\frac{11}{16} = 0.6875 $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Schritt 4\n", "Werden nun alle obigen Schritte zusammengesetzt, so ergibt sich mit \n", "\n", "$$ s = 1 \\quad e = 5 \\quad m = 0.6875 $$\n", "\n", "für die Gleitkommazahl $a$ folgender Wert\n", "\n", "$$a = -1^{s} \\cdot (1.0+m) \\cdot 2^{e-3} = -1 \\cdot 1.6875 \\cdot 2^2 = -6.75$$" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## Aufgabenstellung" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "### Aufgabenteil A" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Wandeln Sie folgende Dezimalzahlen in Binärzahlen um. Beachten Sie dabei den gewünschten Datentyp. \n", "\n", "| Dezimalzahl | digitales Format |\n", "| :--: | :--: |\n", "| 11110 | 8-Bit Darstellung ohne Vorzeichen |\n", "| -52210 | 16-Bit Darstellung mit Vorzeichen | \n", "| 30010 | 16-Bit Darstellung ohne Vorzeichen |\n", "| -11210 | 8-Bit Darstellung mit Vorzeichen | \n", "| 12810 | 8-Bit Darstellung mit Vorzeichen |\n" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "#### Lösungshinweis" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Die Anzahl der Einsen in der binären Darstellung für die ersten drei Zahlen sind: 6, 4, 4. " ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung" ] }, "source": [ "#### Lösungsvorschlag" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung", "hide-cell" ] }, "source": [ ":::{toggle} \n", "* 11110 = 0110 11112\n", "* -52210 = 1000 0010 0000 10102 \n", "* 30010 = 0000 0001 0010 11002\n", "* -11210 = 1111 00002\n", "* nicht möglich, da mit 7 Bit (eines ist für das Vorzeichen vorbehalten) die maximale Zahl 127 ist\n", ":::" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "### Aufgabenteil B" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "Wandeln Sie folgende binäre Gleitkommazahlen (8 Bit) in ihr dezimales Äquivalent um. Verwenden Sie die oben vorgestellte Umwandlung.\n", "\n", "* 010101002\n", "* 111000102\n", "\n", "Welche Gleitkommazahl ist vom Betrag her die kleinste darstellbare Zahl in diesem Format? Hierzu ist es hilfreich zuerst die binäre Darstellung zu bestimmen.\n" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "#### Lösungshinweis\n", "Die beiden umzuwandelnden Zahlen liegen vom Betrag her zwischen 4 und 10. Schreibt man die Gleitkommazahl auf, so sind ab der zweiten Nachkommastelle alle Stellen gleich Null. " ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung" ] }, "source": [ "#### Lösungsvorschlag" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung", "hide-cell" ] }, "source": [ ":::{toggle}\n", "* 0 101 01002 = 5.0\n", "* 1 110 00102 = -9.0\n", ":::" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "### Aufgabenteil C" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bestimmen Sie die binäre Darstellung im obigen hypothetischen 8-Bit-Format folgender Gleitkommazahlen:\n", "\n", "* 1.0\n", "* 0.5\n", "* 1.5\n", "\n", "und optional auch für diese Zahlen:\n", "\n", "* 3.0\n", "* -2.5" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "#### Lösungshinweis\n", "Die Anzahl der Einsen in der binären Darstellung der oberen drei Zahlen ist: 2, 1, 3." ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung" ] }, "source": [ "#### Lösungsvorschlag" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung", "hide-cell" ] }, "source": [ ":::{toggle} \n", "* 0 011 0000\n", "* 0 010 0000\n", "* 0 011 1000\n", "\n", "und \n", "\n", "* 0 100 1000\n", "* 1 100 0100\n", ":::" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "remove_cell", "hide-cell" ] }, "source": [ "### Aufgabenteil D\n", "\n", "Mit der oberen hypothetischen 8-Bit-Darstellung sind nur wenige Gleitkommazahlen abbildbar. Beispielsweise kann die 0.1 in diesem Format nicht exakt dargestellt werden – Sie können es mal versuchen. Bei der Umwandlung ins binäre Format würde dann die nächstgelegene abbildbare Gleitkommazahl gewählt werden.\n", "\n", "Aber auch mit den in der Praxis eingesetzten 32-Bit-Darstellungen, wie nach dem IEEE754 Standard, kann die 0.1 nicht exakt dargestellt werden. Die beiden benachbarten und abbildbaren Gleitkommazahlen sind \n", "\n", "$$ 0.0999999940395 \\le 0.1 \\le 0.10000000149 $$\n", "\n", "Hier ist die größere Zahl näher dran, so dass deren binäre Darstellung für die 0.1 gewählt werden würde. \n", "\n", "Auch die Zahlen 0.2 und 0.3 können nicht exakt dargestellt werden. Wenn Sie nun einen Computer, welcher natürlich nur mit der binären Darstellung rechnen kann, die Summe aus 0.1 und 0.2 bilden lassen, wird das Ergebniss gleich 0.3 sein? " ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung" ] }, "source": [ "#### Lösungsvorschlag" ] }, { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung", "hide-cell" ] }, "source": [ ":::{toggle} \n", "Die Antwort auf diese Frage lautet: Es kommt darauf an. Hierbei ist es wichtig zu verstehen, dass Gleitkommazahlen, wie die 0.1, 0.2 oder auch 0.3 nicht exakt als Gleitkommazahl im Dualsystem dargestellt werden können. Konkret für diese Zahlen heisst das, dass bei der Umwandlung in eine binäre Gleitkommazahl\n", "\n", "* 0.1 zu 0.10000000149,\n", "* 0.2 zu 0.20000000298 und\n", "* 0.3 zu 0.30000001192\n", "\n", "angenäht werden. Hinweis: Nützlich für diese Betrachtung ist ein Gleitkommazahlkonverter, wie dieser [Gleitkommazahlkonverter](https://www.h-schmidt.net/FloatConverter/IEEE754de.html).\n", "\n", "Addiert man nun die binären Repräsentationen von 0.1 und 0.2, ergibt das \n", "\n", "$$\\sf 0.10000000149 + 0.20000000298 = 0.3000000045 $$\n", "\n", "Die Zahl 0.3000000045 kann binär nicht exakt abgebildet werden, sondern wird als 0.30000001192 abgespeichert. Das entspricht exakt der binären Darstellung von 0.3. Damit würde in diesem Fall die Addition von 0.1 und 0.2 in diesem Zahlenformat die 0.3 ergeben.\n", "\n", "Das muss aber nicht immer so sein. Die Addition von 1.1 und 0.2 verdeutlicht dies. Die binären Darstellungen lauten:\n", "\n", "* 0.2 wird binär zu 0.20000000298\n", "* 1.1 wird zu 1.10000002384\n", "\n", "Die Summe beider lautet\n", "\n", "$$ \\sf 0.20000000298 + 1.10000002384 = 1.3000000268 .$$\n", "\n", "Allerdings ist dies keine darstellbare Zahl in diesem Format und wird zu 1.30000007153 umgewandelt. Dies entspricht aber nicht der Darstellung von 1.3, welche 1.29999995232 wäre. Das bedeutet, dass bei der Berechnung obiger Summe folgende Ausgabe zu erwarten wäre\n", "\n", "$$ \\sf 0.2 + 1.1 = 1.30000007153 .$$\n", ":::" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "loesung", "remove_input", "hide-cell" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.1 -> 0.10000000149\n", "0.2 -> 0.20000000298\n", "0.3 -> 0.30000001192\n", "0.1+0.2 -> 0.30000001192\n", "(0.1+0.2)-0.3 -> 0.00000000000\n", "\n", "1.1 -> 1.10000002384\n", "0.2 -> 0.20000000298\n", "1.3 -> 1.29999995232\n", "1.1+0.2 -> 1.30000007153\n", "(1.1+0.2)-1.3 -> 0.00000011921\n" ] } ], "source": [ "import numpy as np\n", "np.set_printoptions(precision=11, floatmode='fixed')\n", "a = np.array([0.1, 0.2, 0.3, 0, 0], dtype='float32')\n", "a[3] = a[0] + a[1]\n", "a[4] = (a[0] + a[1]) - a[2]\n", "print('0.1 -> {:.11f}'.format(a[0]))\n", "print('0.2 -> {:.11f}'.format(a[1]))\n", "print('0.3 -> {:.11f}'.format(a[2]))\n", "print('0.1+0.2 -> {:.11f}'.format(a[3]))\n", "print('(0.1+0.2)-0.3 -> {:.11f}'.format(a[4]))\n", "print()\n", "\n", "a = np.array([1.1, 0.2, 1.3, 0, 0], dtype='float32')\n", "a[3] = a[0] + a[1]\n", "a[4] = (a[0] + a[1]) - a[2]\n", "print('1.1 -> {:.11f}'.format(a[0]))\n", "print('0.2 -> {:.11f}'.format(a[1]))\n", "print('1.3 -> {:.11f}'.format(a[2]))\n", "print('1.1+0.2 -> {:.11f}'.format(a[3]))\n", "print('(1.1+0.2)-1.3 -> {:.11f}'.format(a[4]))" ] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.6" } }, "nbformat": 4, "nbformat_minor": 4 }