From bfd05f1cbb6a43046e1cbe51d3de29321bf20364 Mon Sep 17 00:00:00 2001
From: Sebastien Gilles <sebastien.gilles@inria.fr>
Date: Tue, 21 May 2019 18:41:16 +0200
Subject: [PATCH] Revamp the TP for procedural programming:  make it clearer,
 add one session and put some exercices in a later one to avoid a heavy block
 with more then 10 exercices at once. Solutions have been rewritten to be
 generally more elegant; I have also renounced to separate declaration and
 definition as this was definitely a pain for most participants the first day.

---
 1-ProceduralProgramming/0-main.ipynb          |   5 +-
 1-ProceduralProgramming/2b-TP.ipynb           | 133 ++++++++
 1-ProceduralProgramming/4b-TP.ipynb           | 306 +++---------------
 1-ProceduralProgramming/6b-TP.ipynb           | 232 ++++++++++++-
 TP/1-ProceduralProgramming/CMakeLists.txt     |  17 +-
 .../Solution/exercice1.cpp                    |  62 ++--
 .../Solution/exercice10.cpp                   | 180 +++++------
 .../Solution/exercice11.cpp                   | 198 +++++-------
 .../Solution/exercice12.cpp                   | 219 +++++--------
 .../Solution/exercice2.cpp                    |  67 ++--
 .../Solution/exercice3.cpp                    |  65 ++--
 .../Solution/exercice4.cpp                    |  93 +++---
 .../Solution/exercice5.cpp                    | 109 +++----
 .../Solution/exercice6.cpp                    | 133 ++++----
 .../Solution/exercice7.cpp                    | 138 ++++----
 .../Solution/exercice8.cpp                    | 176 +++++-----
 .../Solution/exercice9.cpp                    | 175 +++++-----
 TP/1-ProceduralProgramming/initial_file.cpp   |  68 ++--
 18 files changed, 1116 insertions(+), 1260 deletions(-)
 create mode 100644 1-ProceduralProgramming/2b-TP.ipynb

diff --git a/1-ProceduralProgramming/0-main.ipynb b/1-ProceduralProgramming/0-main.ipynb
index 5743dca..570fdee 100644
--- a/1-ProceduralProgramming/0-main.ipynb
+++ b/1-ProceduralProgramming/0-main.ipynb
@@ -13,12 +13,13 @@
    "source": [
     "* [Variables, initialisation, affectation](/notebooks/1-ProceduralProgramming/1-Variables.ipynb)\n",
     "* [Condition and loops](/notebooks/1-ProceduralProgramming/2-Conditions-and-loops.ipynb)\n",
+    "    * [TP 1](/notebooks/1-ProceduralProgramming/2b-TP.ipynb)\n",
     "* [Predefined types](/notebooks/1-ProceduralProgramming/3-Types.ipynb)\n",
     "* [Functions](/notebooks/1-ProceduralProgramming/4-Functions.ipynb)\n",
-    "    * [TP 1](/notebooks/1-ProceduralProgramming/4b-TP.ipynb)\n",
+    "    * [TP 2](/notebooks/1-ProceduralProgramming/4b-TP.ipynb)\n",
     "* [Dynamic allocation](/notebooks/1-ProceduralProgramming/5-DynamicAllocation.ipynb)\n",
     "* [Input/output](/notebooks/1-ProceduralProgramming/6-Streams.ipynb)\n",
-    "    * [TP 2](/notebooks/1-ProceduralProgramming/6b-TP.ipynb)"
+    "    * [TP 3](/notebooks/1-ProceduralProgramming/6b-TP.ipynb)"
    ]
   },
   {
diff --git a/1-ProceduralProgramming/2b-TP.ipynb b/1-ProceduralProgramming/2b-TP.ipynb
new file mode 100644
index 0000000..9d7ae09
--- /dev/null
+++ b/1-ProceduralProgramming/2b-TP.ipynb
@@ -0,0 +1,133 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [TP 1](/notebooks/1-ProceduralProgramming/4b-TP.ipynb)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "toc": true
+   },
+   "source": [
+    "<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
+    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Introduction\" data-toc-modified-id=\"Introduction-1\">Introduction</a></span><ul class=\"toc-item\"><li><span><a href=\"#How-to-do-the-TP?\" data-toc-modified-id=\"How-to-do-the-TP?-1.1\">How to do the TP?</a></span></li><li><span><a href=\"#The-problem-we'll-deal-with-throughout-the-TPs\" data-toc-modified-id=\"The-problem-we'll-deal-with-throughout-the-TPs-1.2\">The problem we'll deal with throughout the TPs</a></span></li><li><span><a href=\"#EXERCICE-1:-Adding-a-loop\" data-toc-modified-id=\"EXERCICE-1:-Adding-a-loop-1.3\"><strong>EXERCICE 1: Adding a loop</strong></a></span></li></ul></li></ul></div>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Introduction\n",
+    "\n",
+    "### How to do the TP?\n",
+    "\n",
+    "This [notebook](/notebooks/TP/HowTo.ipynb) explains very briefly your options to run the TP.\n",
+    "\n",
+    "### The problem we'll deal with throughout the TPs\n",
+    "\n",
+    "Any real number can be approximated by the ratio between two integers. \n",
+    "\n",
+    "We will choose here to approximate any real `r` by an expression `numerator / 2^exponent`, where both `numerator` and `exponent` are integers.\n",
+    "\n",
+    "The higher the numerator and exponent values, the more accurate the approximation can be. For example, 0.65 can be approximated successively by:  \n",
+    "* 1 / 2<sup>1</sup> = 0.5  \n",
+    "* 3 / 2<sup>2</sup> = 0.75  \n",
+    "* 5 / 2<sup>3</sup> = 0.625\n",
+    "* ... \n",
+    "\n",
+    "The highest possible numbers will therefore be chosen, within the limits set by the system, i.e. by the number of bits available to encode these numbers.\n",
+    "\n",
+    "As part of the TP, the number of bits allowed to store the numerator will be arbitrarily fixed, and the effect on the accuracy of the approximation will be calculated. Note that if you have N bits to store an integer, the largest possible integer is 2<sup>N</sup> - 1.\n",
+    "\n",
+    "The file you need to start is [provided](/notebooks/TP/1-ProceduralProgramming/initial_file.cpp) in the TP folder of ProceduralProgramming lectures."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### __EXERCICE 1: Adding a loop__\n",
+    "\n",
+    "Write a loop that displays the like of above up to the 2<sup>8</sup> for 0.65.\n",
+    "\n",
+    "_Expected result_:\n",
+    "\n",
+    "0.65 ~ 1 / 2^1  \n",
+    "0.65 ~ 3 / 2^2  \n",
+    "0.65 ~ 5 / 2^3  \n",
+    "0.65 ~ 10 / 2^4  \n",
+    "0.65 ~ 21 / 2^5  \n",
+    "0.65 ~ 42 / 2^6  \n",
+    "0.65 ~ 83 / 2^7  \n",
+    "0.65 ~ 166 / 2^8"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "\n",
+    "© _CNRS 2016_ - _Inria 2018-2019_   \n",
+    "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_  \n",
+    "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_\n",
+    "\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++17",
+   "language": "C++17",
+   "name": "xeus-cling-cpp17"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "-std=c++17"
+  },
+  "latex_envs": {
+   "LaTeX_envs_menu_present": true,
+   "autoclose": false,
+   "autocomplete": true,
+   "bibliofile": "biblio.bib",
+   "cite_by": "apalike",
+   "current_citInitial": 1,
+   "eqLabelWithNumbers": true,
+   "eqNumInitial": 1,
+   "hotkeys": {
+    "equation": "Ctrl-E",
+    "itemize": "Ctrl-I"
+   },
+   "labels_anchors": false,
+   "latex_user_defs": false,
+   "report_style_numbering": false,
+   "user_envs_cfg": false
+  },
+  "toc": {
+   "base_numbering": 1,
+   "nav_menu": {},
+   "number_sections": false,
+   "sideBar": true,
+   "skip_h1_title": true,
+   "title_cell": "Table of contents",
+   "title_sidebar": "Contents",
+   "toc_cell": true,
+   "toc_position": {
+    "height": "calc(100% - 180px)",
+    "left": "10px",
+    "top": "150px",
+    "width": "285.2px"
+   },
+   "toc_section_display": true,
+   "toc_window_display": true
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/1-ProceduralProgramming/4b-TP.ipynb b/1-ProceduralProgramming/4b-TP.ipynb
index 8e6dfc2..6f77c33 100644
--- a/1-ProceduralProgramming/4b-TP.ipynb
+++ b/1-ProceduralProgramming/4b-TP.ipynb
@@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [TP 1](/notebooks/1-ProceduralProgramming/4b-TP.ipynb)"
+    "# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [TP 2](/notebooks/1-ProceduralProgramming/4b-TP.ipynb)"
    ]
   },
   {
@@ -14,56 +14,7 @@
    },
    "source": [
     "<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
-    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Introduction\" data-toc-modified-id=\"Introduction-1\">Introduction</a></span><ul class=\"toc-item\"><li><span><a href=\"#How-to-do-the-TP?\" data-toc-modified-id=\"How-to-do-the-TP?-1.1\">How to do the TP?</a></span></li><li><span><a href=\"#The-problem-we'll-deal-with-throughout-the-TPs\" data-toc-modified-id=\"The-problem-we'll-deal-with-throughout-the-TPs-1.2\">The problem we'll deal with throughout the TPs</a></span></li><li><span><a href=\"#EXERCICE-1:-Adding-a-loop\" data-toc-modified-id=\"EXERCICE-1:-Adding-a-loop-1.3\"><strong>EXERCICE 1: Adding a loop</strong></a></span></li><li><span><a href=\"#EXERCICE-2:-Adding-a-function\" data-toc-modified-id=\"EXERCICE-2:-Adding-a-function-1.4\"><strong>EXERCICE 2: Adding a function</strong></a></span></li><li><span><a href=\"#EXERCICE-3:-compute-the-approximation\" data-toc-modified-id=\"EXERCICE-3:-compute-the-approximation-1.5\"><strong>EXERCICE 3: compute the approximation</strong></a></span></li><li><span><a href=\"#EXERCICE-4:-Search-for-the-best-approximation-for-a-given-maximum-numerator.\" data-toc-modified-id=\"EXERCICE-4:-Search-for-the-best-approximation-for-a-given-maximum-numerator.-1.6\"><strong>EXERCICE 4: Search for the best approximation for a given maximum numerator.</strong></a></span></li><li><span><a href=\"#EXERCICE-5:-Computation-of-the-maximum-numerator-as-a-function-of-the-number-of-bits\" data-toc-modified-id=\"EXERCICE-5:-Computation-of-the-maximum-numerator-as-a-function-of-the-number-of-bits-1.7\"><strong>EXERCICE 5: Computation of the maximum numerator as a function of the number of bits</strong></a></span></li><li><span><a href=\"#EXERCICE-6:-moving-display-to-a-new-intermediate-function\" data-toc-modified-id=\"EXERCICE-6:-moving-display-to-a-new-intermediate-function-1.8\"><strong>EXERCICE 6: moving display to a new intermediate function</strong></a></span></li><li><span><a href=\"#EXERCICE-7:-adding-error-in-display\" data-toc-modified-id=\"EXERCICE-7:-adding-error-in-display-1.9\"><strong>EXERCICE 7: adding error in display</strong></a></span></li><li><span><a href=\"#EXERCICE-8:-Multiplication\" data-toc-modified-id=\"EXERCICE-8:-Multiplication-1.10\"><strong>EXERCICE 8: Multiplication</strong></a></span></li><li><span><a href=\"#EXERCICE-9:-display-sum-of-two-multiply\" data-toc-modified-id=\"EXERCICE-9:-display-sum-of-two-multiply-1.11\">EXERCICE 9: display sum of two <code>multiply</code></a></span></li><li><span><a href=\"#EXERCICE-10:-print-error-in-display_sum()\" data-toc-modified-id=\"EXERCICE-10:-print-error-in-display_sum()-1.12\"><strong>EXERCICE 10: print error in <code>display_sum()</code></strong></a></span></li><li><span><a href=\"#EXERCICE-11:-function-pointers\" data-toc-modified-id=\"EXERCICE-11:-function-pointers-1.13\">EXERCICE 11: function pointers</a></span></li></ul></li></ul></div>"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Introduction\n",
-    "\n",
-    "### How to do the TP?\n",
-    "\n",
-    "This [notebook](/notebooks/TP/HowTo.ipynb) explains very briefly your options to run the TP.\n",
-    "\n",
-    "### The problem we'll deal with throughout the TPs\n",
-    "\n",
-    "Any real number can be approximated by the ratio between two integers. \n",
-    "\n",
-    "We will choose here to approximate any real `r` by an expression `numerator / 2^exponent`, where both `numerator` and `exponent` are integers.\n",
-    "\n",
-    "The higher the numerator and exponent values, the more accurate the approximation can be. For example, 0.65 can be approximated successively by:  \n",
-    "* 1 / 2<sup>1</sup> = 0.5  \n",
-    "* 3 / 2<sup>2</sup> = 0.75  \n",
-    "* 5 / 2<sup>3</sup> = 0.625\n",
-    "* ... \n",
-    "\n",
-    "The highest possible numbers will therefore be chosen, within the limits set by the system, i.e. by the number of bits available to encode these numbers.\n",
-    "\n",
-    "As part of the TP, the number of bits allowed to store the numerator will be arbitrarily fixed, and the effect on the accuracy of the approximation will be calculated. Note that if you have N bits to store an integer, the largest possible integer is 2<sup>N</sup> - 1.\n",
-    "\n",
-    "The file you need to start is [provided](/notebooks/TP/1-ProceduralProgramming/initial_file.cpp) in the TP folder of ProceduralProgramming lectures."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### __EXERCICE 1: Adding a loop__\n",
-    "\n",
-    "Write a loop that displays the like of above up to the 2<sup>8</sup> for 0.65.\n",
-    "\n",
-    "_Expected result_:\n",
-    "\n",
-    "0.65 ~ 1 / 2^1  \n",
-    "0.65 ~ 3 / 2^2  \n",
-    "0.65 ~ 5 / 2^3  \n",
-    "0.65 ~ 10 / 2^4  \n",
-    "0.65 ~ 21 / 2^5  \n",
-    "0.65 ~ 42 / 2^6  \n",
-    "0.65 ~ 83 / 2^7  \n",
-    "0.65 ~ 166 / 2^8"
+    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#EXERCICE-2:-Adding-a-function\" data-toc-modified-id=\"EXERCICE-2:-Adding-a-function-1\"><strong>EXERCICE 2: Adding a function</strong></a></span></li><li><span><a href=\"#EXERCICE-3:-compute-the-approximation\" data-toc-modified-id=\"EXERCICE-3:-compute-the-approximation-2\"><strong>EXERCICE 3: compute the approximation</strong></a></span></li><li><span><a href=\"#EXERCICE-4:-Search-for-the-best-approximation-for-a-given-maximum-numerator.\" data-toc-modified-id=\"EXERCICE-4:-Search-for-the-best-approximation-for-a-given-maximum-numerator.-3\"><strong>EXERCICE 4: Search for the best approximation for a given maximum numerator.</strong></a></span></li><li><span><a href=\"#EXERCICE-5:-Computation-of-the-maximum-numerator-as-a-function-of-the-number-of-bits\" data-toc-modified-id=\"EXERCICE-5:-Computation-of-the-maximum-numerator-as-a-function-of-the-number-of-bits-4\"><strong>EXERCICE 5: Computation of the maximum numerator as a function of the number of bits</strong></a></span></li><li><span><a href=\"#EXERCICE-6:-moving-display-to-a-new-intermediate-function\" data-toc-modified-id=\"EXERCICE-6:-moving-display-to-a-new-intermediate-function-5\"><strong>EXERCICE 6: moving display to a new intermediate function</strong></a></span></li><li><span><a href=\"#EXERCICE-7:-adding-error-in-display\" data-toc-modified-id=\"EXERCICE-7:-adding-error-in-display-6\"><strong>EXERCICE 7: adding error in display</strong></a></span></li></ul></div>"
    ]
   },
   {
@@ -169,11 +120,11 @@
    "source": [
     "int main()\n",
     "{\n",
-    "    display_power_of_2_approx(15, 0.65) ;\n",
-    "    display_power_of_2_approx(255, 0.65) ;\n",
+    "    display_power_of_2_approx(15, 0.65);\n",
+    "    display_power_of_2_approx(255, 0.65);\n",
     "\n",
-    "    display_power_of_2_approx(15, 0.35) ;\n",
-    "    display_power_of_2_approx(255, 0.35) ;\n",
+    "    display_power_of_2_approx(15, 0.35);\n",
+    "    display_power_of_2_approx(255, 0.35);\n",
     "\n",
     "    return EXIT_SUCCESS;\n",
     "}"
@@ -201,11 +152,9 @@
     "\n",
     "The highest usable value for the numerator depends on the number of bits used to represent this integer. \n",
     "\n",
-    "In `display_power_of_2_approx()` arguments, replace the argument designating the maximum value with an argument designating the maximum number of bits and correct the body of the function accordingly, using the `max_int()` function given below.\n",
-    "\n",
-    "On display, replace the maximum numerator with the number of bits. \n",
+    "In `display_power_of_2_approx()` arguments, replace the argument designating the maximum numerator with an argument designating the maximum number of bits and correct the body of the function accordingly, using the `max_int()` function given below.\n",
     "\n",
-    "In the main program, make two loops that vary the number of bits from 2 to 8 in steps of 2, one that calls `display_power_of_2_approx()` for 0.65, and the other for 0.35. "
+    "On display, replace the maximum numerator with the number of bits. \n"
    ]
   },
   {
@@ -221,6 +170,36 @@
     "}"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Use the following `main()` function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main(int argc, char** argv)\n",
+    "{\n",
+    "    static_cast<void>(argc); // to silence warning about unused argc - don't bother \n",
+    "    static_cast<void>(argv); // to silence warning about unused argv - don't bother \n",
+    "        \n",
+    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
+    "        display_power_of_2_approx(Nbits, 0.65);\n",
+    "    \n",
+    "    std::cout << std::endl;\n",
+    "\n",
+    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
+    "        display_power_of_2_approx(Nbits, 0.35);\n",
+    "\n",
+    "    return EXIT_SUCCESS;\n",
+    "}"
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},
@@ -253,7 +232,11 @@
     "\n",
     "It is often advisable to give one main functionality to a given function; we will thefore separate here the computation from the display.\n",
     "\n",
-    "Write a new function named `compute_power_of_2_approx()`, which computes the approximation itself and returns the numerator and the exponent as output arguments; this function will be called in `display_power_of_2_approx()`.\n",
+    "Write a new function named `compute_power_of_2_approx()` that will be called in `display_power_of_2_approx()`.\n",
+    "\n",
+    "This new function should:\n",
+    "* Return the floating point approximation.\n",
+    "* Return (with reference parameters) the numerator and the exponent (that are displayed on screen).\n",
     "\n",
     "Output should remain the same!\n"
    ]
@@ -289,209 +272,6 @@
     "````"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### __EXERCICE 8: Multiplication__\n",
-    "\n",
-    "Write the `multiply()` function that calculates the approximate product of a real by an integer coefficient and returns an integer. \n",
-    "\n",
-    "This function must approximate the real using the `compute_power_of_2_approx()` function above; the returned integer shall use `times_power_of_2()` function.\n",
-    "\n",
-    "The arguments of `multiply()` are the maximum number of bits for approximation, the real and the integer coefficient.\n",
-    "\n",
-    "The new main will be:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "int main(int argc, char** argv)  \n",
-    "{ \n",
-    "    static_cast<void>(argc); // to silence warning about unused argc - don't bother \n",
-    "    static_cast<void>(argv); // to silence warning about unused argv - don't bother \n",
-    "        \n",
-    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
-    "        display_power_of_2_approx(Nbits, 0.65) ;\n",
-    "    \n",
-    "    std::cout << std::endl;\n",
-    "\n",
-    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
-    "        display_power_of_2_approx(Nbits, 0.35) ;\n",
-    "    \n",
-    "    std::cout << std::endl;\n",
-    "\n",
-    "    for (int Nbits = 1; Nbits <= 8; ++Nbits)\n",
-    "    {\n",
-    "        double exact = 0.65 * 3515 + 0.35 * 4832;\n",
-    "        int rounded = round_as_int(exact);\n",
-    "        int approx = multiply(Nbits, 0.65, 3515) + multiply(Nbits, 0.35, 4832);\n",
-    "        std::cout << \"[With \" << Nbits << \" bits]: 0.65 * 3515 + 0.35 * 4832 = \" \n",
-    "            << rounded << \" ~ \" << approx << std::endl;\n",
-    "     }\n",
-    "\n",
-    "    return EXIT_SUCCESS;\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "_Expected result:_\n",
-    "\n",
-    "````\n",
-    "[With 2 bits]: 0.65 ~ 0.75 (3/2^2)  [error = 15/100]\n",
-    "[With 4 bits]: 0.65 ~ 0.625 (10/2^4)  [error = 4/100]\n",
-    "[With 6 bits]: 0.65 ~ 0.65625 (42/2^6)  [error = 1/100]\n",
-    "[With 8 bits]: 0.65 ~ 0.648438 (166/2^8)  [error = 0/100]\n",
-    "\n",
-    "[With 2 bits]: 0.35 ~ 0.375 (3/2^3)  [error = 7/100]\n",
-    "[With 4 bits]: 0.35 ~ 0.34375 (11/2^5)  [error = 2/100]\n",
-    "[With 6 bits]: 0.35 ~ 0.351562 (45/2^7)  [error = 0/100]\n",
-    "[With 8 bits]: 0.35 ~ 0.349609 (179/2^9)  [error = 0/100]\n",
-    "\n",
-    "[With 1 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 2965\n",
-    "[With 2 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4448\n",
-    "[With 3 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4008\n",
-    "[With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857\n",
-    "[With 5 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3967\n",
-    "[With 6 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4004\n",
-    "[With 7 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3977\n",
-    "[With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968\n",
-    "````"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### EXERCICE 9: display sum of two `multiply`\n",
-    "\n",
-    "Exactly as we did previously in exercice 2, move the display of the sum of multiplication result in a dedicated function `display_sum()` (which will hence takes 5 arguments: number of bits, two reals and their associated integer coefficient).\n",
-    "\n",
-    "New main will look like:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [],
-   "source": [
-    "int main(int argc, char** argv)\n",
-    "{\n",
-    "    static_cast<void>(argc); // to silence warning about unused argc - don't bother \n",
-    "    static_cast<void>(argv); // to silence warning about unused argv - don't bother \n",
-    "        \n",
-    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
-    "        display_power_of_2_approx(0.65, Nbits);\n",
-    "\n",
-    "    std::cout << std::endl;\n",
-    "\n",
-    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
-    "        display_power_of_2_approx(0.35, Nbits);\n",
-    "    \n",
-    "    std::cout << std::endl;\n",
-    "    \n",
-    "    for (int Nbits = 1; Nbits <= 8; ++Nbits)\n",
-    "        display_multiply(Nbits, 0.65, 3515, 0.35, 4832);\n",
-    "        \n",
-    "    return EXIT_SUCCESS;\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### __EXERCICE 10: print error in `display_sum()`__\n",
-    "\n",
-    "Modify slightly the function defined above to add display of the error; we will express it over 1000.\n",
-    "\n",
-    "_Expected result_:\n",
-    "\n",
-    "````\n",
-    "[With 2 bits]: 0.65 ~ 0.75 (3/2^2)  [error = 15/100]\n",
-    "[With 4 bits]: 0.65 ~ 0.625 (10/2^4)  [error = 4/100]\n",
-    "[With 6 bits]: 0.65 ~ 0.65625 (42/2^6)  [error = 1/100]\n",
-    "[With 8 bits]: 0.65 ~ 0.648438 (166/2^8)  [error = 0/100]\n",
-    "\n",
-    "[With 2 bits]: 0.35 ~ 0.375 (3/2^3)  [error = 7/100]\n",
-    "[With 4 bits]: 0.35 ~ 0.34375 (11/2^5)  [error = 2/100]\n",
-    "[With 6 bits]: 0.35 ~ 0.351562 (45/2^7)  [error = 0/100]\n",
-    "[With 8 bits]: 0.35 ~ 0.349609 (179/2^9)  [error = 0/100]\n",
-    "\n",
-    "[With 1 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 2965  [error = 254/1000]\n",
-    "[With 2 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4448  [error = 119/1000]\n",
-    "[With 3 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4008  [error = 8/1000]\n",
-    "[With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857  [error = 30/1000]\n",
-    "[With 5 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3967  [error = 2/1000]\n",
-    "[With 6 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4004  [error = 7/1000]\n",
-    "[With 7 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3977  [error = 0/1000]\n",
-    "[With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968  [error = 2/1000]\n",
-    "````\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### EXERCICE 11: function pointers\n",
-    "\n",
-    "Create a `loop()` function that takes as an argument :\n",
-    "\n",
-    "* An initial number of bits\n",
-    "* A final number of bits\n",
-    "* An increment to be applied to the number of bits\n",
-    "* A pointer to a function to be executed for each number of bits\n",
-    "\n",
-    "You will need the following intermediate function to be able to use them in `loop()` (as a specific signature is expected):"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "void display_065(int Nbits)\n",
-    "{ \n",
-    "    display_power_of_2_approx(Nbits, 0.65); \n",
-    "}\n",
-    "\n",
-    "void display_035(int Nbits)\n",
-    "{\n",
-    "    display_power_of_2_approx(Nbits, 0.35); \n",
-    "}\n",
-    "\n",
-    "void display_065_3515_035_4832(int Nbits)\n",
-    "{ \n",
-    "    display_sum(Nbits, 0.65, 3515, 0.35, 4832); \n",
-    "}\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "int main()\n",
-    "{\n",
-    "    loop(2, 8, 2, display_065) ;\n",
-    "    loop(2, 8, 2, display_035) ;\n",
-    "    loop(1, 8, 1, display_065_3515_035_4832) ;\n",
-    "    return EXIT_SUCCESS;\n",
-    "}"
-   ]
-  },
   {
    "cell_type": "markdown",
    "metadata": {},
diff --git a/1-ProceduralProgramming/6b-TP.ipynb b/1-ProceduralProgramming/6b-TP.ipynb
index 2961976..7f7f5be 100644
--- a/1-ProceduralProgramming/6b-TP.ipynb
+++ b/1-ProceduralProgramming/6b-TP.ipynb
@@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [TP 1](/notebooks/1-ProceduralProgramming/7b-TP.ipynb)"
+    "# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [TP 3](/notebooks/1-ProceduralProgramming/7b-TP.ipynb)"
    ]
   },
   {
@@ -14,14 +14,240 @@
    },
    "source": [
     "<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
-    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#EXERCICE-12:-write-in-output-file\" data-toc-modified-id=\"EXERCICE-12:-write-in-output-file-1\">EXERCICE 12: write in output file</a></span></li></ul></div>"
+    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#EXERCICE-8:-Multiplication-by-an-integer\" data-toc-modified-id=\"EXERCICE-8:-Multiplication-by-an-integer-1\"><strong>EXERCICE 8: Multiplication by an integer</strong></a></span></li><li><span><a href=\"#EXERCICE-9:-display-sum-of-two-multiply\" data-toc-modified-id=\"EXERCICE-9:-display-sum-of-two-multiply-2\">EXERCICE 9: display sum of two <code>multiply</code></a></span></li><li><span><a href=\"#EXERCICE-10:-print-error-in-display_sum()\" data-toc-modified-id=\"EXERCICE-10:-print-error-in-display_sum()-3\"><strong>EXERCICE 10: print error in <code>display_sum()</code></strong></a></span></li><li><span><a href=\"#[optional]-EXERCICE-11:-function-pointers\" data-toc-modified-id=\"[optional]-EXERCICE-11:-function-pointers-4\">[optional] EXERCICE 11: function pointers</a></span></li><li><span><a href=\"#[optional]-EXERCICE-12:-write-in-output-file\" data-toc-modified-id=\"[optional]-EXERCICE-12:-write-in-output-file-5\">[optional] EXERCICE 12: write in output file</a></span></li></ul></div>"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### EXERCICE 12: write in output file \n",
+    "### __EXERCICE 8: Multiplication by an integer__\n",
+    "\n",
+    "Write the `multiply()` function that calculates the approximate product of a real by an integer coefficient and returns an integer. \n",
+    "\n",
+    "This function must approximate the real using the `compute_power_of_2_approx()` function above; the returned integer shall use `times_power_of_2()` function.\n",
+    "\n",
+    "The arguments of `multiply()` are the maximum number of bits for approximation, the real and the integer coefficient.\n",
+    "\n",
+    "The new main will be:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main(int argc, char** argv)  \n",
+    "{ \n",
+    "    static_cast<void>(argc); // to silence warning about unused argc - don't bother \n",
+    "    static_cast<void>(argv); // to silence warning about unused argv - don't bother \n",
+    "        \n",
+    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
+    "        display_power_of_2_approx(Nbits, 0.65) ;\n",
+    "    \n",
+    "    std::cout << std::endl;\n",
+    "\n",
+    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
+    "        display_power_of_2_approx(Nbits, 0.35) ;\n",
+    "    \n",
+    "    std::cout << std::endl;\n",
+    "\n",
+    "    for (int Nbits = 1; Nbits <= 8; ++Nbits)\n",
+    "    {\n",
+    "        double exact = 0.65 * 3515;\n",
+    "        int rounded = round_as_int(exact);\n",
+    "        int approx = multiply(Nbits, 0.65, 3515);\n",
+    "        std::cout << \"[With \" << Nbits << \" bits]: 0.65 * 3515 = \" \n",
+    "            << rounded << \" ~ \" << approx << std::endl;\n",
+    "     }\n",
+    "\n",
+    "    return EXIT_SUCCESS;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "_Expected result:_\n",
+    "\n",
+    "````\n",
+    "[With 2 bits]: 0.65 ~ 0.75 (3 / 2^2)  [error = 15/100]\n",
+    "[With 4 bits]: 0.65 ~ 0.625 (10 / 2^4)  [error = 4/100]\n",
+    "[With 6 bits]: 0.65 ~ 0.65625 (42 / 2^6)  [error = 1/100]\n",
+    "[With 8 bits]: 0.65 ~ 0.648438 (166 / 2^8)  [error = 0/100]\n",
+    "\n",
+    "[With 2 bits]: 0.35 ~ 0.375 (3 / 2^3)  [error = 7/100]\n",
+    "[With 4 bits]: 0.35 ~ 0.34375 (11 / 2^5)  [error = 2/100]\n",
+    "[With 6 bits]: 0.35 ~ 0.351562 (45 / 2^7)  [error = 0/100]\n",
+    "[With 8 bits]: 0.35 ~ 0.349609 (179 / 2^9)  [error = 0/100]\n",
+    "\n",
+    "[With 1 bits]: 0.65 * 3515 = 2285 ~ 1757\n",
+    "[With 2 bits]: 0.65 * 3515 = 2285 ~ 2636\n",
+    "[With 3 bits]: 0.65 * 3515 = 2285 ~ 2196\n",
+    "[With 4 bits]: 0.65 * 3515 = 2285 ~ 2196\n",
+    "[With 5 bits]: 0.65 * 3515 = 2285 ~ 2306\n",
+    "[With 6 bits]: 0.65 * 3515 = 2285 ~ 2306\n",
+    "[With 7 bits]: 0.65 * 3515 = 2285 ~ 2279\n",
+    "[With 8 bits]: 0.65 * 3515 = 2285 ~ 2279\n",
+    "````"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### EXERCICE 9: display sum of two `multiply`\n",
+    "\n",
+    "Write a `display_sum` function which will write the computation of the sum of two real numbers through their approximation.\n",
+    "\n",
+    "This function will take 5 arguments:\n",
+    "\n",
+    "* The number of bits to use.\n",
+    "* Two real values.\n",
+    "* Their associated coefficients.\n",
+    "\n",
+    "New main will look like:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int main(int argc, char** argv)\n",
+    "{\n",
+    "    static_cast<void>(argc); // to silence warning about unused argc - don't bother \n",
+    "    static_cast<void>(argv); // to silence warning about unused argv - don't bother \n",
+    "        \n",
+    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
+    "        display_power_of_2_approx(0.65, Nbits);\n",
+    "\n",
+    "    std::cout << std::endl;\n",
+    "\n",
+    "    for (int Nbits = 2; Nbits <= 8; Nbits += 2)\n",
+    "        display_power_of_2_approx(0.35, Nbits);\n",
+    "    \n",
+    "    std::cout << std::endl;\n",
+    "    \n",
+    "    for (int Nbits = 1; Nbits <= 8; ++Nbits)\n",
+    "        display_multiply(Nbits, 0.65, 3515, 0.35, 4832); // to compute 0.65 * 3515 + 0.35 * 4832\n",
+    "        \n",
+    "    return EXIT_SUCCESS;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "_Expected result_:\n",
+    "\n",
+    "    [With 2 bits]: 0.65 ~ 0.75 (3 / 2^2)  [error = 15/100]\n",
+    "    [With 4 bits]: 0.65 ~ 0.625 (10 / 2^4)  [error = 4/100]\n",
+    "    [With 6 bits]: 0.65 ~ 0.65625 (42 / 2^6)  [error = 1/100]\n",
+    "    [With 8 bits]: 0.65 ~ 0.648438 (166 / 2^8)  [error = 0/100]\n",
+    "\n",
+    "    [With 2 bits]: 0.35 ~ 0.375 (3 / 2^3)  [error = 7/100]\n",
+    "    [With 4 bits]: 0.35 ~ 0.34375 (11 / 2^5)  [error = 2/100]\n",
+    "    [With 6 bits]: 0.35 ~ 0.351562 (45 / 2^7)  [error = 0/100]\n",
+    "    [With 8 bits]: 0.35 ~ 0.349609 (179 / 2^9)  [error = 0/100]\n",
+    "\n",
+    "    [With 1 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 2965\n",
+    "    [With 2 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4448\n",
+    "    [With 3 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4008\n",
+    "    [With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857\n",
+    "    [With 5 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3967\n",
+    "    [With 6 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4004\n",
+    "    [With 7 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3977\n",
+    "    [With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### __EXERCICE 10: print error in `display_sum()`__\n",
+    "\n",
+    "Modify slightly the function defined above to add display of the error; we will express it over 1000 (see exercice 7 which was roughly the same!)\n",
+    "\n",
+    "_Expected result_:\n",
+    "\n",
+    "````\n",
+    "[With 2 bits]: 0.65 ~ 0.75 (3/2^2)  [error = 15/100]\n",
+    "[With 4 bits]: 0.65 ~ 0.625 (10/2^4)  [error = 4/100]\n",
+    "[With 6 bits]: 0.65 ~ 0.65625 (42/2^6)  [error = 1/100]\n",
+    "[With 8 bits]: 0.65 ~ 0.648438 (166/2^8)  [error = 0/100]\n",
+    "\n",
+    "[With 2 bits]: 0.35 ~ 0.375 (3/2^3)  [error = 7/100]\n",
+    "[With 4 bits]: 0.35 ~ 0.34375 (11/2^5)  [error = 2/100]\n",
+    "[With 6 bits]: 0.35 ~ 0.351562 (45/2^7)  [error = 0/100]\n",
+    "[With 8 bits]: 0.35 ~ 0.349609 (179/2^9)  [error = 0/100]\n",
+    "\n",
+    "[With 1 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 2965  [error = 254/1000]\n",
+    "[With 2 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4448  [error = 119/1000]\n",
+    "[With 3 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4008  [error = 8/1000]\n",
+    "[With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857  [error = 30/1000]\n",
+    "[With 5 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3967  [error = 2/1000]\n",
+    "[With 6 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 4004  [error = 7/1000]\n",
+    "[With 7 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3977  [error = 0/1000]\n",
+    "[With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968  [error = 2/1000]\n",
+    "````\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### [optional] EXERCICE 11: function pointers\n",
+    "\n",
+    "Create a `loop()` function that takes as an argument :\n",
+    "\n",
+    "* An initial number of bits\n",
+    "* A final number of bits\n",
+    "* An increment to be applied to the number of bits\n",
+    "* A pointer to a function to be executed for each number of bits\n",
+    "\n",
+    "You will need the following intermediate function to be able to use them in `loop()` (as a specific signature is expected):"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void display_065(int Nbits)\n",
+    "{ \n",
+    "    display_power_of_2_approx(Nbits, 0.65); \n",
+    "}\n",
+    "\n",
+    "void display_035(int Nbits)\n",
+    "{\n",
+    "    display_power_of_2_approx(Nbits, 0.35); \n",
+    "}\n",
+    "\n",
+    "void display_065_3515_035_4832(int Nbits)\n",
+    "{ \n",
+    "    display_sum(Nbits, 0.65, 3515, 0.35, 4832); \n",
+    "}\n",
+    "\n",
+    "int main()\n",
+    "{\n",
+    "    loop(2, 8, 2, display_065);\n",
+    "    loop(2, 8, 2, display_035);\n",
+    "    loop(1, 8, 1, display_065_3515_035_4832);\n",
+    "    return EXIT_SUCCESS;\n",
+    "}\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### [optional] EXERCICE 12: write in output file \n",
     "\n",
     "Modify the program so that the `displayXXX` functions take an additional argument: the output stream to which the content should be written. `loop()` will be modified as well.\n",
     "\n",
diff --git a/TP/1-ProceduralProgramming/CMakeLists.txt b/TP/1-ProceduralProgramming/CMakeLists.txt
index 68b573f..12ac830 100644
--- a/TP/1-ProceduralProgramming/CMakeLists.txt
+++ b/TP/1-ProceduralProgramming/CMakeLists.txt
@@ -22,20 +22,33 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
 endif()
 
 
-
 set(CMAKE_CXX_COMPILER clang++ CACHE STRING "C++ compiler")
 set(CMAKE_C_COMPILER clang CACHE STRING "C compiler")
 set(CMAKE_CXX_STANDARD 17 CACHE INTEGER "Version of the C++ standard to use")
 set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "If ON the GNU version of the standard is used.")
-
+    
 project(GettingStartedWithModernCpp_TP_Procedural)
 
+    
+# Option to color the outputs with ninja.
+# Adapted from https://medium.com/@alasher/colored-c-compiler-output-with-ninja-clang-gcc-10bfe7f2b949
+option (FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." True)
+
+if (${FORCE_COLORED_OUTPUT})
+    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+       add_compile_options (-fdiagnostics-color=always)
+    elseif (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang"))
+       add_compile_options (-fcolor-diagnostics)
+    endif ()
+endif ()
+
 
 add_cxx_compiler_flag("-Weverything") # all warnings for clang
 add_cxx_compiler_flag("-Wall") # for gcc (and recognized by clang)
 add_cxx_compiler_flag("-Wextra") # for gcc  (and recognized by clang)
 add_cxx_compiler_flag("-Wno-c++98-compat") # We assume we are using modern C++
 add_cxx_compiler_flag("-Wno-c++98-compat-pedantic") # We assume we are using modern C++
+add_cxx_compiler_flag("-Wno-missing-prototypes") # For this TP we will not separate declarations and definitions
 
 
 add_executable(initial initial_file.cpp)
diff --git a/TP/1-ProceduralProgramming/Solution/exercice1.cpp b/TP/1-ProceduralProgramming/Solution/exercice1.cpp
index bcc9423..3dbb0ce 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice1.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice1.cpp
@@ -1,46 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int i = 1; i <= 8; ++i)
-    {
-        int numerator = round_as_int(0.65 * times_power_of_2(1, i));
-        std::cout << "0.65 ~ " << numerator << " / 2^" << i << std::endl ;
-    }
-  
-    std::cout << std::endl ;
-    
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -56,11 +18,33 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+
+    for (int exponent = 1; exponent < 9; ++exponent)
+    {
+        int numerator = round_as_int(0.65 * times_power_of_2(1, exponent));
+        std::cout << "0.65 ~ " << numerator << " / 2^" << exponent << std::endl;
+    }
+    
+    std::cout << std::endl;
+    
+    return EXIT_SUCCESS;
+}
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice10.cpp b/TP/1-ProceduralProgramming/Solution/exercice10.cpp
index 0bd45a4..cd4e8d1 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice10.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice10.cpp
@@ -1,84 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-
-/*! 
- * \brief Multiply an approximate representation of a double by an integer. 
- * 
- * \param[in] Nbits Number of bits available to represent `value` with the integer representation.
- * \param[in] value Floating point value which is approximated by the integer representation.
- * \param[in] coefficient Integer coefficient by which `value` is multiplied.
- * 
- * \return An approximate integer result of the multiplication.
- */
-int multiply(int Nbits, double value, int coefficient);
-
-
-/*!
- * \brief Display the approximate result of value1 * coefficient1 + value2 * coefficient2 computed with 
- *  precision of `Nbits`.
- */
-void display_sum(int Nbits, double value1, int coefficient1, double value2, int coefficient2);
-
-
-// Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.65) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.35) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 1; Nbits <= 8; ++Nbits)
-        display_sum(Nbits, 0.65, 3515, 0.35, 4832);
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -94,76 +18,120 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    int error = round_as_int(100. * std::fabs(value - approx) / value);
-    
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' 
-        << "  [error = " << error << "/" << "100]" 
-        << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
 }
 
 
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+    
+    const double error = std::fabs(value - approx) / value;
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ")  [error = " << round_as_int(100. * error) << "/100]" << std::endl;
+}
+
+
+
+//! Multiply an approximated value by an integer.
 int multiply(int Nbits, double value, int coefficient)
 {
     int numerator {}, exponent {};
     compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    
+
     return times_power_of_2(numerator * coefficient, -exponent);
 }
 
 
-void display_sum(int Nbits, double value1, int coefficient1, double value2, int coefficient2)
+//! Compute value1 * coefficient1 + value2 * coefficient2 over Nbits bits.
+void display_multiply(int Nbits, double value1, int coefficient1, double value2, int coefficient2)
 {
     double exact = value1 * coefficient1 + value2 * coefficient2;
     int rounded = round_as_int(exact);
     int approx = multiply(Nbits, value1, coefficient1) + multiply(Nbits, value2, coefficient2);
     
-    int error = round_as_int(1000. * std::fabs(exact - approx) / exact);
+    const double error = std::fabs(exact - approx) / exact;
     
     std::cout << "[With " << Nbits << " bits]: " << value1 << " * " << coefficient1 
         << " + " << value2 << " * " << coefficient2 << " = " 
         << rounded << " ~ " << approx 
-        << "  [error = " << error << "/" << "1000]" 
-        << std::endl;    
+        << "  [error = " << round_as_int(1000. * error) <<  "/1000]" <<  std::endl;    
 }
 
 
-int max_int(int Nbits)
-{ 
-    return (times_power_of_2(1, Nbits) - 1);
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.65);
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.35);
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 1; Nbits <= 8; ++Nbits)
+        display_multiply(Nbits, 0.65, 3515, 0.35, 4832); // to compute 0.65 * 3515 + 0.35 * 4832
+    
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice11.cpp b/TP/1-ProceduralProgramming/Solution/exercice11.cpp
index abd16c1..f548416 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice11.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice11.cpp
@@ -1,87 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-
-/*! 
- * \brief Multiply an approximate representation of a double by an integer. 
- * 
- * \param[in] Nbits Number of bits available to represent `value` with the integer representation.
- * \param[in] value Floating point value which is approximated by the integer representation.
- * \param[in] coefficient Integer coefficient by which `value` is multiplied.
- * 
- * \return An approximate integer result of the multiplication.
- */
-int multiply(int Nbits, double value, int coefficient);
-
-
-/*!
- * \brief Display the approximate result of value1 * coefficient1 + value2 * coefficient2 computed with 
- *  precision of `Nbits`.
- */
-void display_sum(int Nbits, double value1, int coefficient1, double value2, int coefficient2);
-
-
-//! Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-//! Loop over the number of bits from `initial` to `final` with `increment` and apply everytime `function`.
-void loop(int initial, int final, int increment, void (*function) (int));
-
-//! Wrapper to be able to pass the function to `loop()`.
-void display_065(int Nbits);
-
-//! Wrapper to be able to pass the function to `loop()`.
-void display_035(int Nbits);
-
-//! Wrapper to be able to pass the function to `loop()`.
-void display_065_3515_035_4832(int Nbits);
-    
-    
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    loop(2, 8, 2, display_065) ;
-    loop(2, 8, 2, display_035) ;
-    loop(1, 8, 1, display_065_3515_035_4832) ;
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -97,103 +18,134 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    int error = round_as_int(100. * std::fabs(value - approx) / value);
-    
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' 
-        << "  [error = " << error << "/" << "100]" 
-        << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
 }
 
 
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+    
+    const double error = std::fabs(value - approx) / value;
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ")  [error = " << round_as_int(100. * error) << "/100]" << std::endl;
+}
+
+
+
+//! Multiply an approximated value by an integer.
 int multiply(int Nbits, double value, int coefficient)
 {
     int numerator {}, exponent {};
     compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    
+
     return times_power_of_2(numerator * coefficient, -exponent);
 }
 
 
-void display_sum(int Nbits, double value1, int coefficient1, double value2, int coefficient2)
+//! Compute value1 * coefficient1 + value2 * coefficient2 over Nbits bits.
+void display_multiply(int Nbits, double value1, int coefficient1, double value2, int coefficient2)
 {
     double exact = value1 * coefficient1 + value2 * coefficient2;
     int rounded = round_as_int(exact);
     int approx = multiply(Nbits, value1, coefficient1) + multiply(Nbits, value2, coefficient2);
     
-    int error = round_as_int(1000. * std::fabs(exact - approx) / exact);
+    const double error = std::fabs(exact - approx) / exact;
     
     std::cout << "[With " << Nbits << " bits]: " << value1 << " * " << coefficient1 
         << " + " << value2 << " * " << coefficient2 << " = " 
         << rounded << " ~ " << approx 
-        << "  [error = " << error << "/" << "1000]" 
-        << std::endl;    
+        << "  [error = " << round_as_int(1000. * error) <<  "/1000]" <<  std::endl;    
 }
 
 
-int max_int(int Nbits)
+void display_065(int Nbits)
 { 
-    return (times_power_of_2(1, Nbits) - 1);
+    display_power_of_2_approx(Nbits, 0.65); 
 }
 
-
-void loop(int initial, int final, int increment, void (*function) (int))
+void display_035(int Nbits)
 {
-    for (int Nbits = initial; Nbits <= final; Nbits += increment)
-        function(Nbits);
-    
-    std::cout << std::endl;
+    display_power_of_2_approx(Nbits, 0.35); 
 }
 
-
-void display_065(int Nbits)
+void display_065_3515_035_4832(int Nbits)
 { 
-    display_power_of_2_approx(Nbits, 0.65); 
+    display_multiply(Nbits, 0.65, 3515, 0.35, 4832); 
 }
 
-
-void display_035(int Nbits)
+void loop(int initial, int final, int increment, void(*display_function)(int))
 {
-    display_power_of_2_approx(Nbits, 0.35); 
+    for (int bits = initial; bits <= final; bits += increment)
+        display_function(bits);
+    
+    std::cout << std::endl;
 }
 
 
-void display_065_3515_035_4832(int Nbits)
-{ 
-    display_sum(Nbits, 0.65, 3515, 0.35, 4832); 
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    loop(2, 8, 2, display_065);
+    loop(2, 8, 2, display_035);
+    loop(1, 8, 1, display_065_3515_035_4832);
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice12.cpp b/TP/1-ProceduralProgramming/Solution/exercice12.cpp
index b71fdd5..1e029c6 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice12.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice12.cpp
@@ -1,97 +1,9 @@
 #include <iostream>
+#include <fstream>
 #include <cmath> // for std::round
-#include <fstream> // for std::ofstream
-
-
-/************************************/
-// Declarations 
-/************************************/
 
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(std::ostream& out, int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-
-/*! 
- * \brief Multiply an approximate representation of a double by an integer. 
- * 
- * \param[in] Nbits Number of bits available to represent `value` with the integer representation.
- * \param[in] value Floating point value which is approximated by the integer representation.
- * \param[in] coefficient Integer coefficient by which `value` is multiplied.
- * 
- * \return An approximate integer result of the multiplication.
- */
-int multiply(int Nbits, double value, int coefficient);
-
-
-/*!
- * \brief Display the approximate result of value1 * coefficient1 + value2 * coefficient2 computed with 
- *  precision of `Nbits`.
- */
-void display_sum(std::ostream& out, int Nbits, double value1, int coefficient1, double value2, int coefficient2);
-
-
-//! Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-//! Loop over the number of bits from `initial` to `final` with `increment` and apply everytime `function`.
-//! \param[in,out] out The output stream onto which the `function` will add content.
-void loop(std::ostream& out, int initial, int final, int increment, void (*function) (std::ostream&, int));
-
-//! Wrapper to be able to pass the function to `loop()`.
-void display_065(std::ostream& out, int Nbits);
-
-//! Wrapper to be able to pass the function to `loop()`.
-void display_035(std::ostream& out, int Nbits);
-
-//! Wrapper to be able to pass the function to `loop()`.
-void display_065_3515_035_4832(std::ostream& out, int Nbits);
-    
-    
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    if (argc != 2)
-    {
-        std::cerr << "Two arguments are expected on command line: the name of the program followed by the "
-            "path of the file in which some of the outputs will be written." << std::endl;
-        exit(EXIT_FAILURE);
-    }
-    
-    // Open the stream to the file.
-    std::ofstream output_file(argv[1]);
-        
-    loop(output_file, 2, 8, 2, display_065);
-    loop(output_file, 2, 8, 2, display_035);
-    loop(std::cout, 1, 8, 1, display_065_3515_035_4832);
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -107,103 +19,144 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(std::ostream& out, int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    int error = round_as_int(100. * std::fabs(value - approx) / value);
-    
-    out << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' 
-        << "  [error = " << error << "/" << "100]" 
-        << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
+}
+
+
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(std::ostream& out, int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+    
+    const double error = std::fabs(value - approx) / value;
+        
+    out << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ")  [error = " << round_as_int(100. * error) << "/100]" << std::endl;
 }
 
 
+
+//! Multiply an approximated value by an integer.
 int multiply(int Nbits, double value, int coefficient)
 {
     int numerator {}, exponent {};
     compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    
+
     return times_power_of_2(numerator * coefficient, -exponent);
 }
 
 
-void display_sum(std::ostream& out, int Nbits, double value1, int coefficient1, double value2, int coefficient2)
+//! Compute value1 * coefficient1 + value2 * coefficient2 over Nbits bits.
+void display_multiply(std::ostream& out, int Nbits, double value1, int coefficient1, double value2, int coefficient2)
 {
     double exact = value1 * coefficient1 + value2 * coefficient2;
     int rounded = round_as_int(exact);
     int approx = multiply(Nbits, value1, coefficient1) + multiply(Nbits, value2, coefficient2);
     
-    int error = round_as_int(1000. * std::fabs(exact - approx) / exact);
+    const double error = std::fabs(exact - approx) / exact;
     
     out << "[With " << Nbits << " bits]: " << value1 << " * " << coefficient1 
         << " + " << value2 << " * " << coefficient2 << " = " 
         << rounded << " ~ " << approx 
-        << "  [error = " << error << "/" << "1000]" 
-        << std::endl;    
+        << "  [error = " << round_as_int(1000. * error) <<  "/1000]" <<  std::endl;    
 }
 
 
-int max_int(int Nbits)
+void display_065(std::ostream& out, int Nbits)
 { 
-    return (times_power_of_2(1, Nbits) - 1);
+    display_power_of_2_approx(out, Nbits, 0.65); 
 }
 
-
-void loop(std::ostream& out, int initial, int final, int increment, void (*function) (std::ostream&, int))
+void display_035(std::ostream& out, int Nbits)
 {
-    for (int Nbits = initial; Nbits <= final; Nbits += increment)
-        function(out, Nbits);
-    
-    out << std::endl;
+    display_power_of_2_approx(out, Nbits, 0.35); 
 }
 
-
-void display_065(std::ostream& out, int Nbits)
+void display_065_3515_035_4832(std::ostream& out, int Nbits)
 { 
-    display_power_of_2_approx(out, Nbits, 0.65); 
+    display_multiply(out, Nbits, 0.65, 3515, 0.35, 4832); 
 }
 
-
-void display_035(std::ostream& out, int Nbits)
+void loop(std::ostream& out, int initial, int final, int increment, void(*display_function)(std::ostream&, int))
 {
-    display_power_of_2_approx(out, Nbits, 0.35); 
+    for (int bits = initial; bits <= final; bits += increment)
+        display_function(out, bits);
+    
+    out << std::endl;
 }
 
 
-void display_065_3515_035_4832(std::ostream& out, int Nbits)
-{ 
-    display_sum(out, Nbits, 0.65, 3515, 0.35, 4832); 
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    if (argc != 2)
+       {
+           std::cerr << "Two arguments are expected on command line: the name of the program followed by the "
+               "path of the file in which some of the outputs will be written." << std::endl;
+           exit(EXIT_FAILURE);
+       }
+    
+   // Open the stream to the file.
+   std::ofstream output_file(argv[1]);
+    
+   loop(output_file, 2, 8, 2, display_065);
+   loop(output_file, 2, 8, 2, display_035);
+   loop(std::cout, 1, 8, 1, display_065_3515_035_4832);
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice2.cpp b/TP/1-ProceduralProgramming/Solution/exercice2.cpp
index aaee379..c1959f4 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice2.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice2.cpp
@@ -1,44 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation.
-void display_power_of_2_approx(double value);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    display_power_of_2_approx(0.65);
-    display_power_of_2_approx(0.35);
-    
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -54,21 +18,42 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
+//! Display the approximation of the given argument for the exponents from 1 to 8.
 void display_power_of_2_approx(double value)
 {
-    for (int i = 1; i <= 8; ++i)
+    for (int exponent = 1; exponent <= 8; ++exponent)
     {
-        int numerator = round_as_int(value * times_power_of_2(1, i));
-        std::cout << value << " ~ " << numerator << " / 2^" << i << std::endl ;
-    }    
+        int numerator = round_as_int(value * times_power_of_2(1, exponent));
+        std::cout << value << " ~ " << numerator << " / 2^" << exponent << std::endl;
+    }
+    
     std::cout << std::endl;
+    
+}
+
+
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+
+    display_power_of_2_approx(.65);
+    display_power_of_2_approx(.35);
+    
+    return EXIT_SUCCESS;
 }
 
diff --git a/TP/1-ProceduralProgramming/Solution/exercice3.cpp b/TP/1-ProceduralProgramming/Solution/exercice3.cpp
index 4137a92..57b5321 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice3.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice3.cpp
@@ -1,44 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation.
-void display_power_of_2_approx(double value);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    display_power_of_2_approx(0.65);
-    display_power_of_2_approx(0.35);
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -54,25 +18,46 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
+//! Display the approximation of the given argument for the exponents from 1 to 8.
 void display_power_of_2_approx(double value)
 {
     for (int exponent = 1; exponent <= 8; ++exponent)
     {
         int denominator = times_power_of_2(1, exponent);        
         int numerator = round_as_int(value * denominator);
-        double approx = static_cast<double>(numerator) / denominator;        
+        double approx = static_cast<double>(numerator) / denominator; 
         
-        std::cout << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' << std::endl;
-    }    
+        std::cout << value << " ~ " << approx << " (" << numerator << 
+            " / 2^" << exponent << ')' << std::endl;
+    }
     
     std::cout << std::endl;
+    
+}
+
+
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+
+    display_power_of_2_approx(.65);
+    display_power_of_2_approx(.35);
+    
+    return EXIT_SUCCESS;
 }
 
diff --git a/TP/1-ProceduralProgramming/Solution/exercice4.cpp b/TP/1-ProceduralProgramming/Solution/exercice4.cpp
index fb0b430..5dbb967 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice4.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice4.cpp
@@ -1,48 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator lesser than `max_numerator`.
-void display_power_of_2_approx(int max_numerator, double value);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    display_power_of_2_approx(15, 0.65) ;
-    display_power_of_2_approx(255, 0.65) ;
-
-    display_power_of_2_approx(15, 0.35) ;
-    display_power_of_2_approx(255, 0.35) ;
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -58,33 +18,62 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_display_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
+{
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
+}
+
+
+//! Display the approximation of the given argument that does not exceed the chosen maximum numerator.
 void display_power_of_2_approx(int max_numerator, double value)
 {
-    int exponent {};
-    int numerator {}, denominator {};
+    int numerator {}, denominator{}, exponent {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_display_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
-    double approx = static_cast<double>(numerator) / denominator;
+    helper_display_power_of_2_approx(value, --exponent, numerator, denominator);
     
-    std::cout << "[With numerator < " << max_numerator << "]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' << std::endl ;
+    double approx = static_cast<double>(numerator) / denominator; 
+        
+    std::cout << "[With numerator <= "<< max_numerator << "]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ')' << std::endl;
+}
+
+
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+
+    display_power_of_2_approx(15, 0.65);
+    display_power_of_2_approx(255, 0.65);
+
+    display_power_of_2_approx(15, 0.35);
+    display_power_of_2_approx(255, 0.35);
+    
+    return EXIT_SUCCESS;
 }
 
diff --git a/TP/1-ProceduralProgramming/Solution/exercice5.cpp b/TP/1-ProceduralProgramming/Solution/exercice5.cpp
index f077243..7733367 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice5.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice5.cpp
@@ -1,53 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-// Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.65) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.35) ;
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -63,40 +18,72 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_display_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
+{
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
+}
+
+
+//! Display the approximation of the given argument that fits in the given number of bits.
 void display_power_of_2_approx(int Nbits, double value)
 {
-    int exponent {};
-    int numerator {}, denominator {};
-    
     int max_numerator = max_int(Nbits);
+    int numerator {}, denominator{}, exponent {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_display_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
-    double approx = static_cast<double>(numerator) / denominator;
+    helper_display_power_of_2_approx(value, --exponent, numerator, denominator);
     
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' << std::endl ;
+    double approx = static_cast<double>(numerator) / denominator; 
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ')' << std::endl;
 }
 
 
-int max_int(int Nbits)
-{ 
-    return (times_power_of_2(1, Nbits) - 1);
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.65) ;
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.35) ;
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice6.cpp b/TP/1-ProceduralProgramming/Solution/exercice6.cpp
index 74b7cce..b7797bf 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice6.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice6.cpp
@@ -1,59 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-// Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.65) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.35) ;
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -69,48 +18,86 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
 }
 
 
-int max_int(int Nbits)
-{ 
-    return (times_power_of_2(1, Nbits) - 1);
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ')' << std::endl;
 }
+
+
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.65) ;
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.35) ;
+
+    return EXIT_SUCCESS;
+}
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice7.cpp b/TP/1-ProceduralProgramming/Solution/exercice7.cpp
index 6c2f61b..93aca81 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice7.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice7.cpp
@@ -1,59 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-// Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.65) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.35) ;
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -69,51 +18,88 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    int error = round_as_int(100. * std::fabs(value - approx) / value);
-    
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' 
-        << "  [error = " << error << "/" << "100]" 
-        << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
 }
 
 
-int max_int(int Nbits)
-{ 
-    return (times_power_of_2(1, Nbits) - 1);
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+    
+    const double error = std::fabs(value - approx) / value;
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ")  [error = " << round_as_int(100. * error) << "/100]" << std::endl;
+}
+
+
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.65) ;
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.35) ;
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice8.cpp b/TP/1-ProceduralProgramming/Solution/exercice8.cpp
index fa2cfbd..ae29fca 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice8.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice8.cpp
@@ -1,83 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-
-/*! 
- * \brief Multiply an approximate representation of a double by an integer. 
- * 
- * \param[in] Nbits Number of bits available to represent `value` with the integer representation.
- * \param[in] value Floating point value which is approximated by the integer representation.
- * \param[in] coefficient Integer coefficient by which `value` is multiplied.
- * 
- * \return An approximate integer result of the multiplication.
- */
-int multiply(int Nbits, double value, int coefficient);
-
-
-// Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.65) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.35) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 1; Nbits <= 8; ++Nbits)
-    {
-        double exact = 0.65 * 3515 + 0.35 * 4832;
-        int rounded = round_as_int(exact);
-        int approx = multiply(Nbits, 0.65, 3515) + multiply(Nbits, 0.35, 4832);
-        std::cout << "[With " << Nbits << " bits]: 0.65 * 3515 + 0.35 * 4832 = " 
-            << rounded << " ~ " << approx << std::endl;
-     }
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -93,60 +18,109 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    int error = round_as_int(100. * std::fabs(value - approx) / value);
-    
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' 
-        << "  [error = " << error << "/" << "100]" 
-        << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
+}
+
+
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+    
+    const double error = std::fabs(value - approx) / value;
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ")  [error = " << round_as_int(100. * error) << "/100]" << std::endl;
 }
 
 
+
+//! Multiply an approximated value by an integer.
 int multiply(int Nbits, double value, int coefficient)
 {
     int numerator {}, exponent {};
     compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    
+
     return times_power_of_2(numerator * coefficient, -exponent);
 }
 
 
-int max_int(int Nbits)
-{ 
-    return (times_power_of_2(1, Nbits) - 1);
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.65);
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.35);
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 1; Nbits <= 8; ++Nbits)
+    {
+        double exact = 0.65 * 3515;
+        int rounded = round_as_int(exact);
+        int approx = multiply(Nbits, 0.65, 3515);
+        std::cout << "[With " << Nbits << " bits]: 0.65 * 3515 = " 
+            << rounded << " ~ " << approx << std::endl;
+     }
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/Solution/exercice9.cpp b/TP/1-ProceduralProgramming/Solution/exercice9.cpp
index 103f1ac..af49ff4 100644
--- a/TP/1-ProceduralProgramming/Solution/exercice9.cpp
+++ b/TP/1-ProceduralProgramming/Solution/exercice9.cpp
@@ -1,84 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-//! Display the approximation of `value` in the proposed representation with the highest possible
-//! numerator that may be represented in `Nbits` bits.
-void display_power_of_2_approx(int Nbits, double value);
-
-
-//! Compute the best possible approximation of `value` with `Nbits`
-//! \param[out] numerator Computed numerator.
-//! \param[out] exponent Computed exponent.
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent);
-
-
-/*! 
- * \brief Multiply an approximate representation of a double by an integer. 
- * 
- * \param[in] Nbits Number of bits available to represent `value` with the integer representation.
- * \param[in] value Floating point value which is approximated by the integer representation.
- * \param[in] coefficient Integer coefficient by which `value` is multiplied.
- * 
- * \return An approximate integer result of the multiplication.
- */
-int multiply(int Nbits, double value, int coefficient);
-
-
-/*!
- * \brief Display the approximate result of value1 * coefficient1 + value2 * coefficient2 computed with 
- *  precision of `Nbits`.
- */
-void display_sum(int Nbits, double value1, int coefficient1, double value2, int coefficient2);
-
-
-// Maximum integer that might be represented with `Nbits` bits.
-int max_int(int Nbits);
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.65) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
-        display_power_of_2_approx(Nbits, 0.35) ;
-    
-    std::cout << std::endl;
-
-    for (int Nbits = 1; Nbits <= 8; ++Nbits)
-        display_sum(Nbits, 0.65, 3515, 0.35, 4832);
-
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -94,60 +18,83 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
-void display_power_of_2_approx(int Nbits, double value)
+// Maximum integer that might be represented with `Nbits` bits.
+int max_int(int Nbits)
+{ 
+    return (times_power_of_2(1, Nbits) - 1);
+}
+
+
+//! Helper function that computes numerator and denominator.
+//! You're not obliged to use a function, but this way you enforce the Don't Repeat Yourself (DRY) principle!
+void helper_compute_power_of_2_approx(double value, int exponent, int& numerator, int& denominator)
 {
-    int numerator {}, exponent {};
-    compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    int denominator = times_power_of_2(1, exponent); 
-    double approx = static_cast<double>(numerator) / denominator;
-    int error = round_as_int(100. * std::fabs(value - approx) / value);
-    
-    std::cout << "[With " << Nbits << " bits]: "
-        << value << " ~ " << approx << " (" << numerator << "/2^" << exponent << ')' 
-        << "  [error = " << error << "/" << "100]" 
-        << std::endl ;
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
 }
 
 
-void compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
+
+//! Compute the best possible approximation of `value` with `Nbits`
+//! \param[out] numerator Computed numerator.
+//! \param[out] exponent Computed exponent.
+//! \return The approximation as a floating point.
+double compute_power_of_2_approx(int Nbits, double value, int& numerator, int& exponent)
 {
-    numerator = exponent = 0;
-    int denominator {};
-    
     int max_numerator = max_int(Nbits);
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
     
     do
     {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
+        // I used here the preffix increment '++exponent' but you may put it on a separate line if you're not 
+        // comfortable with it.
+        helper_compute_power_of_2_approx(value, ++exponent, numerator, denominator);
     }
     while (numerator <= max_numerator);
     
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+    
+    return static_cast<double>(numerator) / denominator;     
 }
 
 
+//! Display the approximation of the given argument that fits in the given number of bits.
+void display_power_of_2_approx(int Nbits, double value)
+{
+    int numerator {}, exponent {};
+    const double approx = compute_power_of_2_approx(Nbits, value, numerator, exponent);
+    
+    const double error = std::fabs(value - approx) / value;
+        
+    std::cout << "[With " << Nbits << " bits]: " << value << " ~ " << approx << " (" << numerator << 
+        " / 2^" << exponent << ")  [error = " << round_as_int(100. * error) << "/100]" << std::endl;
+}
+
+
+
+//! Multiply an approximated value by an integer.
 int multiply(int Nbits, double value, int coefficient)
 {
     int numerator {}, exponent {};
     compute_power_of_2_approx(Nbits, value, numerator, exponent);
-    
+
     return times_power_of_2(numerator * coefficient, -exponent);
 }
 
 
-void display_sum(int Nbits, double value1, int coefficient1, double value2, int coefficient2)
+//! Compute value1 * coefficient1 + value2 * coefficient2 over Nbits bits.
+void display_multiply(int Nbits, double value1, int coefficient1, double value2, int coefficient2)
 {
     double exact = value1 * coefficient1 + value2 * coefficient2;
     int rounded = round_as_int(exact);
@@ -158,7 +105,29 @@ void display_sum(int Nbits, double value1, int coefficient1, double value2, int
 }
 
 
-int max_int(int Nbits)
-{ 
-    return (times_power_of_2(1, Nbits) - 1);
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.65);
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 2; Nbits <= 8; Nbits += 2)
+        display_power_of_2_approx(Nbits, 0.35);
+    
+    std::cout << std::endl;
+
+    for (int Nbits = 1; Nbits <= 8; ++Nbits)
+        display_multiply(Nbits, 0.65, 3515, 0.35, 4832); // to compute 0.65 * 3515 + 0.35 * 4832
+    
+
+    return EXIT_SUCCESS;
 }
+
diff --git a/TP/1-ProceduralProgramming/initial_file.cpp b/TP/1-ProceduralProgramming/initial_file.cpp
index 6f84362..2139f26 100644
--- a/TP/1-ProceduralProgramming/initial_file.cpp
+++ b/TP/1-ProceduralProgramming/initial_file.cpp
@@ -1,49 +1,8 @@
 #include <iostream>
 #include <cmath> // for std::round
 
-/************************************/
-// Declarations 
-/************************************/
-
 
 //! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent);
-
-
-//! Round to `x` the nearest integer.
-int round_as_int(double x);
-
-
-
-/************************************/
-// Main function
-/************************************/
-
-int main(int argc, char** argv)
-{
-    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
-    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
-        
-    int num1 = round_as_int(0.65 * times_power_of_2(1, 1));
-    std::cout << "0.65 ~ " << num1 << " / 2^1" << std::endl ;
-  
-    int num2 = round_as_int(0.65 * times_power_of_2(1, 2));
-    std::cout << "0.65 ~ " << num2 << " / 2^2" << std::endl ;
-  
-    int num3 = round_as_int(0.65 * times_power_of_2(1, 3));
-    std::cout << "0.65 ~ " << num3 << " / 2^3" << std::endl ;
-  
-    std::cout << std::endl ;
-    
-    return EXIT_SUCCESS;
-}
-
-
-/************************************/
-// Definitions
-/************************************/
-
-
 int times_power_of_2(int number, int exponent)
 {
     while (exponent > 0)
@@ -59,11 +18,36 @@ int times_power_of_2(int number, int exponent)
     
     return number;
 }
+    
 
-
+//! Round to `x` the nearest integer.
 int round_as_int(double x)
 {
     return static_cast<int>(std::round(x));
 }
 
 
+
+/************************************/
+// Main function
+/************************************/
+
+int main(int argc, char** argv)
+{
+    static_cast<void>(argc); // to silence warning about unused argc - don't bother 
+    static_cast<void>(argv); // to silence warning about unused argv - don't bother 
+        
+    int numerator1 = round_as_int(0.65 * times_power_of_2(1, 1));
+    std::cout << "0.65 ~ " << numerator1 << " / 2^1" << std::endl ;
+  
+    int numerator2 = round_as_int(0.65 * times_power_of_2(1, 2));
+    std::cout << "0.65 ~ " << numerator2 << " / 2^2" << std::endl ;
+  
+    int numerator3 = round_as_int(0.65 * times_power_of_2(1, 3));
+    std::cout << "0.65 ~ " << numerator3 << " / 2^3" << std::endl ;
+  
+    std::cout << std::endl ;
+    
+    return EXIT_SUCCESS;
+}
+
-- 
GitLab