diff --git a/4-Templates/0-main.ipynb b/4-Templates/0-main.ipynb
index 92606b41357f257eb47326b21ef7a6d903c0958d..b86e105b0c2d9515ec2d34e9ed91a7fa32d851e9 100644
--- a/4-Templates/0-main.ipynb
+++ b/4-Templates/0-main.ipynb
@@ -12,10 +12,10 @@
    "metadata": {},
    "source": [
     "* [Introduction to the concept of templates](/notebooks/4-Templates/1-Intro.ipynb)\n",
-    "    * [TP 11](/notebooks/4-Templates/1b-TP.ipynb)\n",
+    "    * [TP 12](/notebooks/4-Templates/1b-TP.ipynb)\n",
     "* [Specialization](/notebooks/4-Templates/2-Specialization.ipynb)\n",
     "* [Special syntax: typename, template and mandatory this](/notebooks/4-Templates/3-Syntax.ipynb)\n",
-    "    * [TP 12](/notebooks/4-Templates/3b-TP.ipynb)\n",
+    "    * [TP 13](/notebooks/4-Templates/3b-TP.ipynb)\n",
     "* [Metaprogramming](/notebooks/4-Templates/4-Metaprogramming.ipynb)\n",
     "* [Hints to more advanced concepts with templates](/notebooks/4-Templates/5-MoreAdvanced.ipynb)"
    ]
diff --git a/4-Templates/1b-TP.ipynb b/4-Templates/1b-TP.ipynb
index 769b44ee98302bcd74cd6d1c5d96b85b6ce4c437..bb1426b186dfc52bb373e59d25de82af0e004182 100644
--- a/4-Templates/1b-TP.ipynb
+++ b/4-Templates/1b-TP.ipynb
@@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# [Getting started in C++](/) - [Templates](/notebooks/4-Templates/0-main.ipynb) - [TP 11](/notebooks/4-Templates/1b-TP.ipynb)"
+    "# [Getting started in C++](/) - [Templates](/notebooks/4-Templates/0-main.ipynb) - [TP 12](/notebooks/4-Templates/1b-TP.ipynb)"
    ]
   },
   {
@@ -14,7 +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></li><li><span><a href=\"#EXERCICE-37:-make-PowerOfTwoApprox-a-template-class\" data-toc-modified-id=\"EXERCICE-37:-make-PowerOfTwoApprox-a-template-class-2\">EXERCICE 37: make <code>PowerOfTwoApprox</code> a template class</a></span></li><li><span><a href=\"#EXERCICE-38:-consistency\" data-toc-modified-id=\"EXERCICE-38:-consistency-3\">EXERCICE 38: consistency</a></span></li><li><span><a href=\"#[optional]-EXERCICE-39:-crude-error-handling-for-the-overflow-issue\" data-toc-modified-id=\"[optional]-EXERCICE-39:-crude-error-handling-for-the-overflow-issue-4\">[optional] EXERCICE 39: crude error handling for the overflow issue</a></span></li><li><span><a href=\"#EXERCICE-40:-more-template-functions\" data-toc-modified-id=\"EXERCICE-40:-more-template-functions-5\">EXERCICE 40: more template functions</a></span></li><li><span><a href=\"#[optional]-EXERCICE-41:-another-error-handling...\" data-toc-modified-id=\"[optional]-EXERCICE-41:-another-error-handling...-6\">[optional] EXERCICE 41: another error handling...</a></span></li></ul></div>"
+    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Introduction\" data-toc-modified-id=\"Introduction-1\">Introduction</a></span></li><li><span><a href=\"#Context:-when-int-is-not-enough\" data-toc-modified-id=\"Context:-when-int-is-not-enough-2\">Context: when <code>int</code> is not enough</a></span></li><li><span><a href=\"#EXERCICE-31:-make-PowerOfTwoApprox-a-template-class\" data-toc-modified-id=\"EXERCICE-31:-make-PowerOfTwoApprox-a-template-class-3\">EXERCICE 31: make <code>PowerOfTwoApprox</code> a template class</a></span></li><li><span><a href=\"#EXERCICE-32:-follow-the-thread...\" data-toc-modified-id=\"EXERCICE-32:-follow-the-thread...-4\">EXERCICE 32: follow the thread...</a></span></li></ul></div>"
    ]
   },
   {
@@ -30,251 +30,140 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### EXERCICE 37: make `PowerOfTwoApprox` a template class\n",
-    "\n",
-    "The integer type used for the `numerator_ `attribute of the `PowerOfTwoApprox` class was chosen arbitrarily. Make it a class template parameter.\n",
-    "\n",
-    "Only this attribute will be modified: the denominator and the number of bits remain `int`.\n",
-    "\n",
-    "Make sure to modify:\n",
-    "\n",
-    "* The type of the data attribute.\n",
-    "* The type returned by the `Numerator()` method.\n",
-    "\n",
-    "In the `TestDisplay` classes, we will for the moment keep instantiating the version with `int`.\n",
-    "\n",
-    "**IMPORTANT:** For the friendship declaration in `PowerOfTwoApprox` to `operator*`, you need to specify another template for the function: you can't use the same as the class one:\n",
-    "\n",
-    "````\n",
-    "template<class T>\n",
-    "class Foo\n",
-    "{\n",
-    "\n",
-    "    friend void MyFunction(Foo<T>); // doesn't do what you really want!\n",
-    "\n",
-    "};\n",
-    "````\n",
-    "\n",
-    "````\n",
-    "template<class T>\n",
-    "class Foo\n",
-    "{\n",
-    "\n",
-    "    template<class U>\n",
-    "    friend void MyFunction(Foo<U>); // Ok!\n",
-    "\n",
-    "};\n",
-    "````\n",
-    "\n",
-    "\n"
+    "###  Context: when `int` is not enough\n",
+    "\n",
+    "So far, we have not put much stress on our representation: \n",
+    " \n",
+    " - We have always used positive values (spoiler: negative don't work...)\n",
+    " - We have also never try to reach the limit of the integer representation.\n",
+    " \n",
+    "If we do that and ask the loop up to 32 bits, we'll see things fall apart (obviously faster with the sum of two products, as we handle greater values).\n",
+    " \n",
+    "We'll see in the next chapter how to deal with errors, but first we will try to fix the 32 bits case to just change the internal integer representation we use.\n",
+    " \n",
+    "We will therefore add a degreee of freedom and let the end user choose the type of integer to use through the use of a template.\n",
+    "\n",
+    "Replacing everything in one step is very error-prone and is definitively not what I do: I really recommend to change part of it, do a commit (in a real project) and thus proceed incrementally until you reach the target state. \n",
+    "\n",
+    "Compiler is really your friend here: make sure explicit conversions deliver awarning helps you to check whether you didn't forget a substitution somewhere (compiler warnings will be dealt in a [further notebook](/notebooks/6-InRealEnvironment/3-Compilers.ipynb); in the TP the one is activated in the CMake, and if you're using an online compiler utility make sure there is `-Wconversion` on the command line)."
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### EXERCICE 38: consistency\n",
-    "\n",
-    "So far, we aren't very self-consistent: we loosen the constraint on the type used to store the numerator, but it is used up against `int` anywhere else. \n",
-    "\n",
-    "To highlight this, change `PowerOfTwoApprox` instantiation by replacing `int` by `short`: you should see warnings pop up...\n",
-    "\n",
-    "To do so properly, you will have to make some classes and functions template. As you will see, doing such a change is rather cumbersome: it is better whenever possible to identify as soon as possible whether a template parameter is required or not.\n",
-    "\n",
-    "We will do so step by step, each exercice dealing with part of the changes.\n",
-    "\n",
-    "In the first step, we will:\n",
-    "\n",
-    "* Modify both `operator*` signatures so that the return type and the argument use the template parameter rather than `int`.\n",
-    "* Make `TestDisplaySum` a template class as well: as it uses up directly `operator*`, you have to do it now.\n",
-    "\n",
-    "**DON'T PANIC:** You should see warnings to solve... and disturbing runtime effects: the computation gets stuck (we were not very aware so far of overflow issues and we end up here with infinite or at least very long loops...)\n",
-    "\n",
-    "Don't get me wrong: the issue is not the templates themselves, but the fact our code is not robust enough and that we didn't see it previously as we worked on types and values (no more than 16 bits...) for which the potentiel problems were not appearant."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### [optional] EXERCICE 39: crude error handling for the overflow issue\n",
-    "\n",
-    "This exercice is not template-related, but as often in software programming, we have obviously to deal swiftly with the unforeseen issue at hand so that we can keep working on what we intended to implement in the first place.\n",
-    "\n",
-    "We will provide several fixes: we want to be able to track down when overflow occurs, and be able to print with `PrintNumericalError()` method that an overflow happens rather than a garbage value.\n",
-    "\n",
-    "To do so, a boolean argument should be added to:\n",
-    "\n",
-    "- `PowerOfTwoApprox` constructor _[input/output]_\n",
-    "- `TestDisplay::PrintNumericalError()` method _[input]_\n",
-    "- `times_power_of_2()` function _[input/output]_\n",
-    "- `max_int()` function _[input/output]_\n",
-    "\n",
-    "that is set to true if an overflow occurred.\n",
-    "\n",
-    "The two overflows to track down are:\n",
+    "### EXERCICE 31: make `PowerOfTwoApprox` a template class\n",
     "\n",
-    "- In `PowerOfTwoApprox` constructor:\n",
+    "Transform the type of `PowerOfTwoApprox::numerator_ ` into a class template parameter.\n",
     "\n",
-    "If in the loop the numerator or the denominator is less than the one computed at the previous iteration, an overflow occurred. Implement a test and when this happens, exit the loop, print a message about the issue and set arbitrarily numerator and exponent to 0 \n",
+    "Only this attribute will be modified: the exponent and the number of bits remain `int`.\n",
     "\n",
-    "- In `times_power_of_2`: \n",
-    "\n",
-    "Before multiplying by 2., check number is less than half the maximum possible value for the type (use `std::numeric_limits<>::max()`).\n",
-    "\n",
-    "We'll see [later](/notebooks/5-UsefulConceptsAndSTL/1-ErrorHandling.ipynb) how to deal more cleanly with error handlings.\n",
-    "\n",
-    "The output should look something like:\n",
-    "\n",
-    "````\n",
-    "[With 4 bits]: 0.65 ~ 0.625  (10/2^4)  [error = 38462/1000000]\n",
-    "[With 8 bits]: 0.65 ~ 0.648438  (166/2^8)  [error = 2404/1000000]\n",
-    "[With 12 bits]: 0.65 ~ 0.649902  (2662/2^12)  [error = 150/1000000]\n",
-    "[With 16 bits]: 0.65 ~ 0.649994  (42598/2^16)  [error = 9/1000000]\n",
-    "\n",
-    "[With 4 bits]: 0.35 ~ 0.34375  (11/2^5)  [error = 17857/1000000]\n",
-    "[With 8 bits]: 0.35 ~ 0.349609  (179/2^9)  [error = 1116/1000000]\n",
-    "[With 12 bits]: 0.35 ~ 0.349976  (2867/2^13)  [error = 70/1000000]\n",
-    "[With 16 bits]: 0.35 ~ 0.349998  (45875/2^17)  [error = 4/1000000]\n",
+    "Make sure to modify:\n",
     "\n",
-    "[With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857  [error = 29930/1000000]\n",
-    "[With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968  [error = 2012/1000000]\n",
-    "[With 12 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 252/1000000]\n",
-    "Overflow in times_power_of_2 with number = 1073741824 and exponent = 1\n",
-    "Overflow happened in PowerOfTwoApprox constructor for value 0.65 over 16 bits; everything is therefore set arbitrarily to zero at the moment.\n",
-    "Overflow happened in PowerOfTwoApprox constructor for value 0.35 over 16 bits; everything is therefore set arbitrarily to zero at the moment.\n",
-    "[With 16 bits]: Overflow!\n",
-    "````"
+    "* The type of the data attribute.\n",
+    "* The type returned by the `GetNumerator()` method.\n",
+    "\n",
+    "In the `TestDisplay` classes, we will for the moment keep instantiating the version with `int` (remember: we proceed with incremental steps).\n",
+    "\n",
+    "We will start with an 'easy' case and call the instantiation for a `long`; warning conversions are fully expected (see explanation above).\n",
+    "\n",
+    "_Expected results (that don't fix anything to the issue found in preamble so far):_\n",
+    "\n",
+    "    [With 4 bits]: 0.65 ~ 0.625  (10/2^4)  [error = 38462/1000000]\n",
+    "    [With 8 bits]: 0.65 ~ 0.648438  (166/2^8)  [error = 2404/1000000]\n",
+    "    [With 12 bits]: 0.65 ~ 0.649902  (2662/2^12)  [error = 150/1000000]\n",
+    "    [With 16 bits]: 0.65 ~ 0.649994  (42598/2^16)  [error = 9/1000000]\n",
+    "    [With 20 bits]: 0.65 ~ 0.65  (681574/2^20)  [error = 1/1000000]\n",
+    "    [With 24 bits]: 0.65 ~ 0.65  (10905190/2^24)  [error = 0/1000000]\n",
+    "    [With 28 bits]: 0.65 ~ 0.65  (174483046/2^28)  [error = 0/1000000]\n",
+    "    [With 32 bits]: 0.65 ~ 1  (1/2^0)  [error = 538462/1000000]\n",
+    "\n",
+    "    [With 4 bits]: 0.35 ~ 0.34375  (11/2^5)  [error = 17857/1000000]\n",
+    "    [With 8 bits]: 0.35 ~ 0.349609  (179/2^9)  [error = 1116/1000000]\n",
+    "    [With 12 bits]: 0.35 ~ 0.349976  (2867/2^13)  [error = 70/1000000]\n",
+    "    [With 16 bits]: 0.35 ~ 0.349998  (45875/2^17)  [error = 4/1000000]\n",
+    "    [With 20 bits]: 0.35 ~ 0.35  (734003/2^21)  [error = 0/1000000]\n",
+    "    [With 24 bits]: 0.35 ~ 0.35  (11744051/2^25)  [error = 0/1000000]\n",
+    "    [With 28 bits]: 0.35 ~ 0.35  (187904819/2^29)  [error = 0/1000000]\n",
+    "    [With 32 bits]: 0.35 ~ 0  (0/2^0)  [error = 1000000/1000000]\n",
+    "\n",
+    "    [With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857  [error = 299/10000]\n",
+    "    [With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968  [error = 20/10000]\n",
+    "    [With 12 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "    [With 16 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "    [With 20 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ -2167  [error = 15450/10000]\n",
+    "    [With 24 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 8  [error = 9980/10000]\n",
+    "    [With 28 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 0  [error = 10000/10000]\n",
+    "    [With 32 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3515  [error = 1159/10000]"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### EXERCICE 40: more template functions\n",
-    "\n",
-    "We will first heed the warnings: there is a type inconsistency due to the fact this function expects `int` and is fed `short`. Make some functions template ones to fix some of the warnings: `times_power_of_2`, `max_int` and `round_as_int`.\n",
-    "\n",
-    "**WARNING:** You may have a hard time fixing the one concerning `operator*` due to a pesky \n",
-    "\n",
-    "````\n",
-    " warning: implicit conversion loses\n",
-    "      integer precision: 'int' to 'short' [-Wconversion]\n",
-    "    return times_power_of_2(approx.Numerator() * coefficient, -approx.Exponent());\n",
-    "````\n",
-    "\n",
-    "This is due to a specificity I was not aware of before preparing this very TP: an arithmetic operator involving two `short` actually returns an `int`! For more of this, see this [StackOverflow question](https://stackoverflow.com/questions/24371868/why-must-a-short-be-converted-to-an-int-before-arithmetic-operations-in-c-and-c). I actually wasn't aware of this because I never use `short`: I was told long ago it was often a pessimization compared to a mere `int` and didn't dig deeper than that; the issue we met here seems to confirm it is quirky to use.\n",
-    "\n",
-    "One can fix the warning with an additional `static_cast`:\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "// Doesn't run in Xeus-cling\n",
+    "### EXERCICE 32: follow the thread...\n",
     "\n",
-    "template<class IntT>\n",
-    "IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)\n",
-    "{\n",
-    "    // static_cast to deal with the `short` case\n",
-    "    return static_cast<IntT>(times_power_of_2(approx.Numerator() * coefficient, -approx.Exponent()));\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "If you're doing such a cast though, you should end up with something like:\n",
+    "Your compiler should not be happy and tell you something like (here clang output with unfortunately the colors lost):\n",
     "\n",
     "````\n",
-    "[With 4 bits]: 0.65 ~ 0.625  (10/2^4)  [error = 38462/1000000]\n",
-    "[With 8 bits]: 0.65 ~ 0.648438  (166/2^8)  [error = 2404/1000000]\n",
-    "[With 12 bits]: 0.65 ~ 0.649902  (2662/2^12)  [error = 150/1000000]\n",
-    "[With 16 bits]: 0.65 ~ 0.649994  (42598/2^16)  [error = 9/1000000]\n",
+    "../exercice31.cpp:84:49: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]\n",
+    "  return times_power_of_2(approx.GetNumerator() * coefficient, -approx.GetExponent());\n",
+    "         ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~\n",
+    "../exercice31.cpp:362:64: note: in instantiation of function template specialization 'operator*<long>' requested here\n",
+    "    int approx = approximation1 * coefficient1  + coefficient2 * approximation2;\n",
+    "````    \n",
     "\n",
-    "[With 4 bits]: 0.35 ~ 0.34375  (11/2^5)  [error = 17857/1000000]\n",
-    "[With 8 bits]: 0.35 ~ 0.349609  (179/2^9)  [error = 1116/1000000]\n",
-    "[With 12 bits]: 0.35 ~ 0.349976  (2867/2^13)  [error = 70/1000000]\n",
-    "[With 16 bits]: 0.35 ~ 0.349998  (45875/2^17)  [error = 4/1000000]\n",
+    "Let's humour the compiler and 'propagate' the template... which will not be a trivial journey:\n",
     "\n",
-    "[With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ -2286  [error = 1574950/1000000]\n",
-    "[With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 1  [error = 999748/1000000]\n",
-    "[With 12 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 0  [error = 1000000/1000000]\n",
-    "Overflow in times_power_of_2 with number = 16384 and exponent = 2\n",
-    "Overflow happened in PowerOfTwoApprox constructor for value 0.65 over 16 bits; everything is therefore set arbitrarily to zero at the moment.\n",
-    "Overflow in times_power_of_2 with number = 16384 and exponent = 2\n",
-    "Overflow happened in PowerOfTwoApprox constructor for value 0.35 over 16 bits; everything is therefore set arbitrarily to zero at the moment.\n",
-    "[With 16 bits]: Overflow!\n",
-    "````"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### [optional] EXERCICE 41: another error handling...\n",
+    "* You will first have to make your own operator* template functions.\n",
+    "* As the operator is used directly in `TestDisplayMultiply`, you will also have to make that class a template class.\n",
     "\n",
-    "_Optional: you may want to take the solution directly!_\n",
+    "At this point the code should be able to compile... but there are still loose ends, as your compiler will tell you (more or less clearly):\n",
     "\n",
-    "Previous exercice should also underline another limitation: we may detect the errors in building a `PowerOfTwoApprox`, but all bets are off when we perform arithmetics... Once again templates aren't the cause of our issue, it's just that the problem was hidden with the `int` used beforehand.\n",
+    "* `times_power_of_2()` should also be transformed into a template function. Therefore `max_int()` should as well.\n",
+    "* `round_as_int()` should also be modified\n",
+    "* And also `helper_compute_power_of_2_approx()` if you are using the proposed solution.\n",
     "\n",
-    "The issue we have now is that in plain arithmetic operations between `short`, we may overflow, especially considering our test example in which coefficients are already in the thousands.\n",
+    "* And finally `TestDisplay::PrintLine()` as well. At the moment, keep hardcoding the type for `TestDisplayPowerOfTwoApprox` which is not (yet) a template class.\n",
     "\n",
-    "This [StackOverflow post](https://stackoverflow.com/questions/199333/how-to-detect-unsigned-integer-multiply-overflow) provides an interesting non-standard feature introduced in clang and gcc to deal with this: special functions that tell if an operation will overflow (other replies give hints to do so manually).\n",
+    "The code should at this point compile again...\n",
     "\n",
-    "The functions to use are:\n",
+    "But there is still a line which might be wrong (unless you were very cautious) without compiler warning: make sure the template argument is used in `PowerOfTwoApprox<IntT>::operator double`. This one was tricky as the code was \n",
     "\n",
     "````\n",
-    "__builtin_add_overflow(T a, T b, T* sum)\n",
-    "__builtin_mul_overflow(T a, T b, T* product)\n",
+    "int denominator = times_power_of_2(1, exponent_);\n",
     "````\n",
     "\n",
-    "where T is the type considered; these functions return 0 if no overflow occurs (and result is in this case given in third argument).\n",
-    "\n",
-    "Use them in `TestDisplaySum<IntT>::Display()` and `operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)` to control the arithmetic operations there.\n",
-    "\n",
-    "Expected result is something like:\n",
-    "\n",
-    "````\n",
-    "[With 4 bits]: 0.65 ~ 0.625  (10/2^4)  [error = 38462/1000000]\n",
-    "[With 8 bits]: 0.65 ~ 0.648438  (166/2^8)  [error = 2404/1000000]\n",
-    "[With 12 bits]: 0.65 ~ 0.649902  (2662/2^12)  [error = 150/1000000]\n",
-    "[With 16 bits]: 0.65 ~ 0.649994  (42598/2^16)  [error = 9/1000000]\n",
-    "\n",
-    "[With 4 bits]: 0.35 ~ 0.34375  (11/2^5)  [error = 17857/1000000]\n",
-    "[With 8 bits]: 0.35 ~ 0.349609  (179/2^9)  [error = 1116/1000000]\n",
-    "[With 12 bits]: 0.35 ~ 0.349976  (2867/2^13)  [error = 70/1000000]\n",
-    "[With 16 bits]: 0.35 ~ 0.349998  (45875/2^17)  [error = 4/1000000]\n",
-    "\n",
-    "Overflow in 3515 * 10\n",
-    "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned.\n",
-    "Overflow in 4832 * 11\n",
-    "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned.\n",
-    "Overflow in 3515 * 10/2^4 + 4832 * 11/2^5\n",
-    "[With 4 bits]: Overflow!\n",
-    "Overflow in 3515 * 166\n",
-    "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned.\n",
-    "Overflow in 4832 * 179\n",
-    "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned.\n",
-    "Overflow in 3515 * 166/2^8 + 4832 * 179/2^9\n",
-    "[With 8 bits]: Overflow!\n",
-    "Overflow in 3515 * 2662\n",
-    "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned.\n",
-    "Overflow in 4832 * 2867\n",
-    "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned.\n",
-    "Overflow in 3515 * 2662/2^12 + 4832 * 2867/2^13\n",
-    "[With 12 bits]: Overflow!\n",
-    "Overflow in times_power_of_2 with number = 16384 and exponent = 2\n",
-    "Overflow happened in PowerOfTwoApprox constructor for value 0.65 over 16 bits; everything is therefore set arbitrarily to zero at the moment.\n",
-    "Overflow in times_power_of_2 with number = 16384 and exponent = 2\n",
-    "Overflow happened in PowerOfTwoApprox constructor for value 0.35 over 16 bits; everything is therefore set arbitrarily to zero at the moment.\n",
-    "[With 16 bits]: Overflow!\n",
-    "````\n"
+    "which doesn't have to trigger a warning: `1` is an `int`... So the `int` specialization of `times_power_of_2`, and that is used to compute the floating point value returned! And you may end up with an unwanted `inf` instead of the expected numeric value. This is yet another reminder that magic numbers are dangerous, even if they look as innocuous as a 1...\n",
+    "\n",
+    "_Expected results (with `long`):_\n",
+    "\n",
+    "     [With 4 bits]: 0.65 ~ 0.625  (10/2^4)  [error = 38462/1000000]\n",
+    "     [With 8 bits]: 0.65 ~ 0.648438  (166/2^8)  [error = 2404/1000000]\n",
+    "     [With 12 bits]: 0.65 ~ 0.649902  (2662/2^12)  [error = 150/1000000]\n",
+    "     [With 16 bits]: 0.65 ~ 0.649994  (42598/2^16)  [error = 9/1000000]\n",
+    "     [With 20 bits]: 0.65 ~ 0.65  (681574/2^20)  [error = 1/1000000]\n",
+    "     [With 24 bits]: 0.65 ~ 0.65  (10905190/2^24)  [error = 0/1000000]\n",
+    "     [With 28 bits]: 0.65 ~ 0.65  (174483046/2^28)  [error = 0/1000000]\n",
+    "     [With 32 bits]: 0.65 ~ 0.65  (2791728742/2^32)  [error = 0/1000000]\n",
+    "\n",
+    "     [With 4 bits]: 0.35 ~ 0.34375  (11/2^5)  [error = 17857/1000000]\n",
+    "     [With 8 bits]: 0.35 ~ 0.349609  (179/2^9)  [error = 1116/1000000]\n",
+    "     [With 12 bits]: 0.35 ~ 0.349976  (2867/2^13)  [error = 70/1000000]\n",
+    "     [With 16 bits]: 0.35 ~ 0.349998  (45875/2^17)  [error = 4/1000000]\n",
+    "     [With 20 bits]: 0.35 ~ 0.35  (734003/2^21)  [error = 0/1000000]\n",
+    "     [With 24 bits]: 0.35 ~ 0.35  (11744051/2^25)  [error = 0/1000000]\n",
+    "     [With 28 bits]: 0.35 ~ 0.35  (187904819/2^29)  [error = 0/1000000]\n",
+    "     [With 32 bits]: 0.35 ~ 0.35  (3006477107/2^33)  [error = 0/1000000]\n",
+    "\n",
+    "     [With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857  [error = 299/10000]\n",
+    "     [With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968  [error = 20/10000]\n",
+    "     [With 12 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "     [With 16 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "     [With 20 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "     [With 24 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "     [With 28 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]\n",
+    "     [With 32 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 2/10000]"
    ]
   },
   {
diff --git a/4-Templates/3b-TP.ipynb b/4-Templates/3b-TP.ipynb
index 8d2725e1be1e49a544a9354a9d17727a3fd7bc1d..29bda61c6dcab642969de689b317e93796585287 100644
--- a/4-Templates/3b-TP.ipynb
+++ b/4-Templates/3b-TP.ipynb
@@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# [Getting started in C++](/) - [Templates](/notebooks/4-Templates/0-main.ipynb) - [TP 12](/notebooks/4-Templates/3b-TP.ipynb)"
+    "# [Getting started in C++](/) - [Templates](/notebooks/4-Templates/0-main.ipynb) - [TP 13](/notebooks/4-Templates/3b-TP.ipynb)"
    ]
   },
   {
@@ -14,123 +14,29 @@
    },
    "source": [
     "<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
-    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#EXERCICE-42:-make-TestDisplayPowerOfTwoApprox-a-template-class\" data-toc-modified-id=\"EXERCICE-42:-make-TestDisplayPowerOfTwoApprox-a-template-class-1\">EXERCICE 42: make <code>TestDisplayPowerOfTwoApprox</code> a template class</a></span></li><li><span><a href=\"#[optional]-EXERCICE-43:-char-display\" data-toc-modified-id=\"[optional]-EXERCICE-43:-char-display-2\">[optional] EXERCICE 43: <code>char</code> display</a></span></li><li><span><a href=\"#EXERCICE-44:-integer-template-argument\" data-toc-modified-id=\"EXERCICE-44:-integer-template-argument-3\">EXERCICE 44: integer template argument</a></span></li></ul></div>"
+    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#EXERCICE-33:-make-TestDisplayPowerOfTwoApprox-a-template-class\" data-toc-modified-id=\"EXERCICE-33:-make-TestDisplayPowerOfTwoApprox-a-template-class-1\">EXERCICE 33: make <code>TestDisplayPowerOfTwoApprox</code> a template class</a></span></li><li><span><a href=\"#EXERCICE-34:-integer-template-argument\" data-toc-modified-id=\"EXERCICE-34:-integer-template-argument-2\">EXERCICE 34: integer template argument</a></span></li></ul></div>"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### EXERCICE 42: make `TestDisplayPowerOfTwoApprox` a template class\n",
+    "### EXERCICE 33: make `TestDisplayPowerOfTwoApprox` a template class\n",
     "\n",
-    "Now we will make `TestDisplayPowerOfTwoApprox` (and therefore its derived classes) a template class. Don't forget to modify `TestDisplayPowerOfTwoApprox<IntT>::Display()` and make the local `PowerOfTwoApprox` object the templated type!\n",
+    "Now we will make `TestDisplayPowerOfTwoApprox` (and therefore its derived classes) a template class. We will therefore remove the hardcoded `long` we introduced in previous exercice.\n",
     "\n",
     "In the derived classes, you will need to help the compiler to figure out inheritance is at play, with `this` or an appropriate alias.\n",
     "\n",
-    "Try it with the following `main()`:\n",
-    "\n",
-    "````\n",
-    "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",
-    "    TestDisplayContainer container(3);\n",
-    "    container.Register(new TestDisplayPowerOfTwoApprox065<int>(1000000));\n",
-    "    container.Register(new TestDisplayPowerOfTwoApprox035<int>(1000000));\n",
-    "    container.Register(new TestDisplaySum<int>(1000000));\n",
-    "    \n",
-    "    loop(4, 16, 4, container);\n",
-    "\n",
-    "    return EXIT_SUCCESS;\n",
-    "}\n",
-    "````\n",
-    "\n",
-    "You should get:\n",
-    "\n",
-    "````\n",
-    "[With 4 bits]: 0.65 ~ 0.625  (10/2^4)  [error = 38462/1000000]\n",
-    "[With 8 bits]: 0.65 ~ 0.648438  (166/2^8)  [error = 2404/1000000]\n",
-    "[With 12 bits]: 0.65 ~ 0.649902  (2662/2^12)  [error = 150/1000000]\n",
-    "[With 16 bits]: 0.65 ~ 0.649994  (42598/2^16)  [error = 9/1000000]\n",
-    "\n",
-    "[With 4 bits]: 0.35 ~ 0.34375  (11/2^5)  [error = 17857/1000000]\n",
-    "[With 8 bits]: 0.35 ~ 0.349609  (179/2^9)  [error = 1116/1000000]\n",
-    "[With 12 bits]: 0.35 ~ 0.349976  (2867/2^13)  [error = 70/1000000]\n",
-    "[With 16 bits]: 0.35 ~ 0.349998  (45875/2^17)  [error = 4/1000000]\n",
-    "\n",
-    "[With 4 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3857  [error = 29930/1000000]\n",
-    "[With 8 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3968  [error = 2012/1000000]\n",
-    "[With 12 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 252/1000000]\n",
-    "[With 16 bits]: 0.65 * 3515 + 0.35 * 4832 = 3976 ~ 3975  [error = 252/1000000]\n",
-    "````\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### [optional] EXERCICE 43: `char` display\n",
-    "\n",
-    "I'm not sure you would be willing to try it given the work `short` already gave, but you may use an even shorter type to represent an integer: `char`!\n",
-    "\n",
-    "Replace the `main` by the following:\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "// Not executable as a Xeus-cling cell!\n",
-    "\n",
-    "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",
-    "    {\n",
-    "        TestDisplayContainer container(4);\n",
-    "        container.Register(new TestDisplayPowerOfTwoApprox065<int>(1000000));\n",
-    "        container.Register(new TestDisplayPowerOfTwoApprox035<int>(1000000));\n",
-    "        container.Register(new TestDisplaySum<int>(1000000));\n",
-    "        \n",
-    "        loop(4, 16, 4, container);\n",
-    "    }\n",
-    "    \n",
-    "    {\n",
-    "        TestDisplayContainer container(2);\n",
-    "        container.Register(new TestDisplayPowerOfTwoApprox065<char>(1000));\n",
-    "        container.Register(new TestDisplayPowerOfTwoApprox065<unsigned char>(1000));\n",
-    "        loop(1, 8, 1, container);\n",
-    "    }\n",
-    "\n",
-    "    return EXIT_SUCCESS;\n",
-    "}"
+    "Expected should result the same... but now the end-user may modify at one place the type if he wants to try with another type."
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "You should observe gibberish like:\n",
+    "### EXERCICE 34: integer template argument\n",
     "\n",
-    "````\n",
-    "Overflow in times_power_of_2 with number = @ and exponent = 1\n",
-    "````\n",
-    "\n",
-    "Patch the outputs so that char integers are properly printed as numbers."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### EXERCICE 44: integer template argument\n",
-    "\n",
-    "Make `TestDisplayContainer` a template class which template argument is an integer `SizeN` that specifies the number of elements that might be stored inside (data attribute `size_` is of course no longer required!)\n",
+    "Make `TestDisplayContainer` a template class which template argument is an integer `CapacityN` that specifies the number of elements that might be stored inside (data attribute `capacity_` is of course no longer required!)\n",
     "\n",
     "There are several school of thoughts about the type you should give this integer:\n",
     "\n",
@@ -138,10 +44,9 @@
     "````\n",
     "static_assert(SizeN > 0)\n",
     "````\n",
-    "* You may prefer to use an `unsigned int` - personally I like to use this type when a quantity has no business being negative.\n",
+    "* You may prefer to use an `unsigned int` - personally I like to use unsigned types when a quantity has no business being negative.\n",
     "* You may even prefer `std::size_t`, which is for more distribution an alias for `unsigned long`. This might seem overkill, but it is the choice in the standard library containers.\n",
-    "\n",
-    "In the proposed solution I will choose the first solution to illustrate `static_assert`, but in a true project I would probably take the third one.\n"
+    "\n"
    ]
   },
   {
diff --git a/TP/4-Templates/CMakeLists.txt b/TP/4-Templates/CMakeLists.txt
index 1a54201dd982c5ecfbbf8f4d244566396d6b6f76..ab4029ccb76df6f8f3b68c63da5abdaa89821bd2 100644
--- a/TP/4-Templates/CMakeLists.txt
+++ b/TP/4-Templates/CMakeLists.txt
@@ -1,51 +1,14 @@
 cmake_minimum_required(VERSION 3.9)
 
-# Add a compiler flag only if it is accepted.
-# This macro is usually defined once and for all in a specific file which is included in the CMakeLists.txt in which
-# you need it. 
-include(CheckCXXCompilerFlag)
-macro(add_cxx_compiler_flag _flag)
-  string(REPLACE "-" "_" _flag_var ${_flag})
-  check_cxx_compiler_flag("${_flag}" CXX_COMPILER_${_flag_var}_OK)
-
-  if(CXX_COMPILER_${_flag_var}_OK)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}")
-  endif()
-endmacro()
-
-if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
-  message(STATUS "Setting build type to 'Debug' as none was specified.")
-  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
-  # Set the possible values of build type for cmake-gui
-  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
-    "MinSizeRel" "RelWithDebInfo")
-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.")
+include(../../cmake/Settings.cmake)
 
 project(GettingStartedWithModernCpp_TP_Template)
 
-
-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("-Wconversion")# for gcc
-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-padded")
-
+include(../../cmake/AfterProjectSettings.cmake)   
 
 add_executable(initial initial_file.cpp)
 
-#add_executable(exercice37 exercice37.cpp)
-#add_executable(exercice38 exercice38.cpp)
-#add_executable(exercice39 exercice39.cpp)
-#add_executable(exercice40 exercice40.cpp)
-#add_executable(exercice41 exercice41.cpp)
-#add_executable(exercice42 exercice42.cpp)
-#add_executable(exercice43 exercice43.cpp)
-#add_executable(exercice44 exercice44.cpp)
\ No newline at end of file
+# add_executable(exercice31 exercice31.cpp)
+# add_executable(exercice32 exercice32.cpp)
+# add_executable(exercice33 exercice33.cpp)
+# add_executable(exercice34 exercice34.cpp)
\ No newline at end of file
diff --git a/TP/4-Templates/Solution/exercice31.cpp b/TP/4-Templates/Solution/exercice31.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4dbfb8ce995c1c5765bda87eb2a898e9f897d9d
--- /dev/null
+++ b/TP/4-Templates/Solution/exercice31.cpp
@@ -0,0 +1,506 @@
+#include <iostream>
+#include <sstream> // for std::ostringstream
+#include <string>
+#include <cmath> // for std::round
+
+
+//! Returns `number` * (2 ^ `exponent`) 
+int times_power_of_2(int number, int exponent)
+{
+    while (exponent > 0)
+    { 
+        number *= 2; 
+        exponent -= 1; 
+    }
+    while (exponent < 0)
+    { 
+        number /= 2;
+        exponent += 1 ; 
+    }
+    
+    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);
+}
+
+
+//! Class to group the two integers used in the approximation we define.
+template<class IntT>
+class PowerOfTwoApprox
+{
+public:
+    
+    //! Compute the best possible approximation of `value` with `Nbits`
+    PowerOfTwoApprox(int Nbits, double value);
+
+    //! \return The approximation as a floating point.
+    explicit operator double() const;
+    
+    //! Accessor to numerator.
+    IntT GetNumerator() const;
+    
+    //! Accessor to exponent.
+    int GetExponent() const;
+    
+ 
+        
+private:
+        
+    IntT numerator_ {};
+    int exponent_ {};    
+};  
+
+
+template<class IntT>
+std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approximation)
+{
+    out << approximation.GetNumerator() << "/2^" << approximation.GetExponent();
+    return out;
+}
+
+
+/*! 
+ * \brief Multiply the approximate representation by an integer. 
+ * 
+ * \param[in] coefficient Integer coefficient by which the object is multiplied.
+ * 
+ * \return An approximate integer result of the multiplication.
+ */
+template<class IntT>
+int operator*(int coefficient, const PowerOfTwoApprox<IntT>& approx)
+{
+  return times_power_of_2(approx.GetNumerator() * coefficient, -approx.GetExponent());
+}
+ 
+
+template<class IntT> 
+int operator*(const PowerOfTwoApprox<IntT>& approx, int coefficient)
+{
+  return coefficient * approx;
+}
+
+
+//! 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!
+//! Note: could be put in the struct... but may be kept a free function as well! We will see much later
+//! the anonymous namespace, in which I would typically put such a free function.
+template<class IntT>
+void helper_compute_power_of_2_approx(double value, int exponent, IntT& numerator, int& denominator)
+{
+    denominator = times_power_of_2(1, exponent);   
+    numerator = round_as_int(value * denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::PowerOfTwoApprox(int Nbits, double value)
+{
+    int max_numerator = max_int(Nbits);
+    
+    auto& numerator = numerator_;
+    int& exponent = exponent_;    
+    
+    numerator = 0;
+    exponent = 0;
+    int denominator {};
+    
+    do
+    {
+        // 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);
+    
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::operator double() const
+{
+    int denominator = times_power_of_2(1, exponent_);
+    return static_cast<double>(numerator_) / denominator;
+}
+
+
+template<class IntT>
+IntT PowerOfTwoApprox<IntT>::GetNumerator() const
+{
+    return numerator_;
+}
+
+
+template<class IntT>
+int PowerOfTwoApprox<IntT>::GetExponent() const
+{
+    return exponent_;
+}
+
+
+enum class RoundToInteger { no, yes };
+
+
+class TestDisplay
+{
+public:
+    
+    //! Constructor which sets the only the resolution (i.e. the maximum index upon which error is defined).
+    TestDisplay(int resolution);
+    
+    //! To make TestDisplay an abstract class.
+    virtual ~TestDisplay();
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits) const = 0;
+
+
+protected:
+    
+   /*!
+    * \brief  Print a line with information about error.
+    *
+    * \param[in] optional_string1 String that might appear just after the "[With N bits]:".
+    * \param[in] optional_string2 String that might appear just before the "[error = ...]".
+    * \param[in] do_round_to_integer If yes, the exact result is approximated as an integer.
+    */
+   void PrintLine(int Nbits, double exact, double approx,
+                  std::string optional_string1 = "", std::string optional_string2 = "",
+                  RoundToInteger do_round_to_integer = RoundToInteger::no) const;
+                  
+private:
+    
+    //! Resolution.
+    const int resolution_;
+  
+};
+
+
+TestDisplay::TestDisplay(int resolution)
+: resolution_(resolution)
+{ }
+
+
+TestDisplay::~TestDisplay() = default;
+
+
+void TestDisplay::operator()(int Nbits) const
+{
+    static_cast<void>(Nbits); // neutralize warning about unused argument at no runtime cost.
+}
+
+
+void TestDisplay::PrintLine(int Nbits, double exact, double approx,
+                            std::string optional_string1, std::string optional_string2,
+                            RoundToInteger do_round_to_integer) const
+{
+    int error = round_as_int(resolution_ * std::fabs(exact - approx) / exact);
+ 
+    std::cout << "[With " << Nbits << " bits]: " << optional_string1
+        << (do_round_to_integer == RoundToInteger::yes ? round_as_int(exact) : exact)  << " ~ " << approx
+        << optional_string2
+        << "  [error = " << error << "/" << resolution_ << "]" 
+        << std::endl;    
+}
+
+
+class TestDisplayPowerOfTwoApprox : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox(int resolution);
+    
+    //! Destructor
+    virtual ~TestDisplayPowerOfTwoApprox() override;
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits)const override = 0;
+    
+protected:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value) const;
+    
+};
+
+
+TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
+: TestDisplay(resolution)
+{ }    
+
+TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
+
+
+void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
+{
+    PowerOfTwoApprox<long> approximation(Nbits, value);
+
+    const double approx = static_cast<double>(approximation);
+    
+    std::ostringstream oconv;
+    oconv << "  (" << approximation << ")";    
+    PrintLine(Nbits, value, approx, "", oconv.str());
+}
+
+
+class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox065(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox065() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
+: TestDisplayPowerOfTwoApprox(resolution)
+{ }
+
+
+TestDisplayPowerOfTwoApprox065::~TestDisplayPowerOfTwoApprox065() = default;
+
+
+void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
+{
+    Display(Nbits, 0.65);    
+}
+
+
+class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox035(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox035() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
+: TestDisplayPowerOfTwoApprox(resolution)
+{ }
+
+TestDisplayPowerOfTwoApprox035::~TestDisplayPowerOfTwoApprox035() = default;
+
+
+void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
+{
+    Display(Nbits, 0.35);    
+}
+
+
+
+class TestDisplayMultiply : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    TestDisplayMultiply(int resolution);
+    
+    //! To make the class a concrete one.
+    virtual ~TestDisplayMultiply() override;
+    
+    
+    //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+        
+private:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value1, int coefficient1, double value2, int coefficient2) const;
+    
+};
+
+
+TestDisplayMultiply::TestDisplayMultiply(int resolution)
+: TestDisplay(resolution)
+{ }
+
+TestDisplayMultiply::~TestDisplayMultiply() = default;
+
+
+void TestDisplayMultiply::operator()(int Nbits) const
+{
+    Display(Nbits, 0.65, 3515, 0.35, 4832);
+}
+
+
+void TestDisplayMultiply::Display(int Nbits, double value1, int coefficient1, double value2, int coefficient2) const
+{
+    double exact = value1 * coefficient1 + value2 * coefficient2;
+    
+    PowerOfTwoApprox<long> approximation1(Nbits, value1);
+    PowerOfTwoApprox<long> approximation2(Nbits, value2);    
+    
+//    int approx = coefficient1 * approximation1 + coefficient2 * approximation2;
+    int approx = approximation1 * coefficient1  + coefficient2 * approximation2;
+    
+    std::ostringstream oconv;
+    oconv << value1 << " * " << coefficient1 << " + " << value2 << " * " << coefficient2 << " = ";
+    
+    PrintLine(Nbits, exact, static_cast<double>(approx), oconv.str(), "", RoundToInteger::yes);
+}
+
+
+//! Function for error handling. We will see later how to fulfill the same functionality more properly.
+[[noreturn]] void error(std::string explanation)
+{
+    std::cout << "ERROR: " << explanation << std::endl;
+    exit(EXIT_FAILURE);
+}
+
+
+class TestDisplayContainer
+{
+public:
+    
+    //! Constructor.
+    TestDisplayContainer(std::size_t capacity);
+    
+    //! Destructor.
+    ~TestDisplayContainer();
+
+    //! Add a new test_display_register.
+    //! At each call, the item to be registered is put at the first available position and internal current_position_
+    //! is incremented. If the end-user attempts to register more than three items, the error() function is called.
+    void Register(TestDisplay* test_display);
+    
+    //! Accessor to the i-th object in the container.
+    const TestDisplay& operator[](std::size_t i) const;
+    
+    //! Get the number of elements actually stored in the class (nullptr don't count).
+    std::size_t GetSize() const;
+    
+    
+private:
+    
+    //! Get the maximal number of elements that might be stored in the container.
+    std::size_t GetCapacity() const;
+    
+private:    
+    
+    //! Maximum number of items that might be registered in the container.
+    const std::size_t capacity_;
+    
+    //! List of all known `TestDisplay` objects.
+    TestDisplay** list_;
+    
+    //! Index to place the next register object. If '3', no more object may be registered.
+    std::size_t current_position_ {};
+
+};
+
+
+TestDisplayContainer::TestDisplayContainer(std::size_t capacity)
+: capacity_(capacity)
+{
+    list_ = new TestDisplay*[capacity];
+    
+    for (auto i = 0ul; i < capacity; ++i)
+        list_[i] = nullptr;
+}
+
+
+TestDisplayContainer::~TestDisplayContainer()
+{
+    for (auto i = 0ul; i < capacity_; ++i)
+        delete list_[i];
+    
+    delete[] list_; // don't forget the [] to delete an array!
+}
+
+
+void TestDisplayContainer::Register(TestDisplay* test_display)
+{
+    if (current_position_ >= capacity_)
+        error("TestDisplayContainer is already full; impossible to register a new element!");
+    
+    list_[current_position_] = test_display;
+    ++current_position_;
+}
+
+
+const TestDisplay& TestDisplayContainer::operator[](std::size_t i) const
+{
+    if (i >= GetCapacity())
+        error("You try to access an element out of bounds!");
+    
+    if (list_[i] == nullptr) // equivalent to i >= GetSize()
+        error("You try to access an element that was never initialized!");
+    
+    return *list_[i];    
+}
+
+
+std::size_t TestDisplayContainer::GetCapacity() const
+{
+    return capacity_;
+}
+
+
+std::size_t TestDisplayContainer::GetSize() const
+{
+    return current_position_;
+}
+
+
+//! For each container stored, loop oover all those bits and print the result on screen.
+void loop(int initial_Nbit, int final_Nbit, int increment_Nbit, const TestDisplayContainer& container)
+{
+    for (auto i = 0ul; i < container.GetSize(); ++i)
+    {
+        decltype(auto) current_test_display = container[i];
+            
+        for (int Nbits = initial_Nbit; Nbits <= final_Nbit; Nbits += increment_Nbit)
+            current_test_display(Nbits);
+        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      
+
+    TestDisplayContainer container(3);
+    
+    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
+    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
+    container.Register(new TestDisplayMultiply(10000));
+    
+    loop(4, 32, 4, container);
+    
+    return EXIT_SUCCESS;
+}
+
diff --git a/TP/4-Templates/Solution/exercice32.cpp b/TP/4-Templates/Solution/exercice32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d6031e4719fc670b8f6aa99170b7f1c2109a39af
--- /dev/null
+++ b/TP/4-Templates/Solution/exercice32.cpp
@@ -0,0 +1,523 @@
+#include <iostream>
+#include <sstream> // for std::ostringstream
+#include <string>
+#include <cmath> // for std::round
+
+
+//! Returns `number` * (2 ^ `exponent`) 
+template<class IntT>
+IntT times_power_of_2(IntT number, int exponent)
+{
+    constexpr IntT two = static_cast<IntT>(2);    
+    
+    while (exponent > 0)
+    { 
+        number *= two; 
+        exponent -= 1; 
+    }
+    while (exponent < 0)
+    { 
+        number /= two;
+        exponent += 1 ; 
+    }
+    
+    return number;
+}
+    
+
+//! Round to `x` the nearest integer.
+template<class IntT>
+IntT round_as_int(double x)
+{
+    return static_cast<IntT>(std::round(x));
+}
+
+
+// Maximum integer that might be represented with `Nbits` bits.
+template<class IntT>
+IntT max_int(int Nbits)
+{ 
+    constexpr IntT one = static_cast<IntT>(1);
+    return (times_power_of_2(one, Nbits) - one);
+}
+
+
+//! Class to group the two integers used in the approximation we define.
+template<class IntT>
+class PowerOfTwoApprox
+{
+public:
+    
+    //! Compute the best possible approximation of `value` with `Nbits`
+    PowerOfTwoApprox(int Nbits, double value);
+
+    //! \return The approximation as a floating point.
+    explicit operator double() const;
+    
+    //! Accessor to numerator.
+    IntT GetNumerator() const;
+    
+    //! Accessor to exponent.
+    int GetExponent() const;
+    
+ 
+        
+private:
+        
+    IntT numerator_ {};
+    int exponent_ {};    
+};  
+
+
+template<class IntT>
+std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approximation)
+{
+    out << approximation.GetNumerator() << "/2^" << approximation.GetExponent();
+    return out;
+}
+
+
+/*! 
+ * \brief Multiply the approximate representation by an integer. 
+ * 
+ * \param[in] coefficient Integer coefficient by which the object is multiplied.
+ * 
+ * \return An approximate integer result of the multiplication.
+ */
+template<class IntT>
+IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
+{
+  return times_power_of_2(approx.GetNumerator() * coefficient, -approx.GetExponent());
+}
+ 
+
+template<class IntT> 
+IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
+{
+  return coefficient * approx;
+}
+
+
+//! 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!
+//! Note: could be put in the struct... but may be kept a free function as well! We will see much later
+//! the anonymous namespace, in which I would typically put such a free function.
+template<class IntT>
+void helper_compute_power_of_2_approx(double value, int exponent, IntT& numerator, IntT& denominator)
+{
+    constexpr IntT one = static_cast<IntT>(1);
+    denominator = times_power_of_2(one, exponent);   
+    numerator = round_as_int<IntT>(value * denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::PowerOfTwoApprox(int Nbits, double value)
+{
+    IntT max_numerator = max_int<IntT>(Nbits);
+    
+    auto& numerator = numerator_;
+    int& exponent = exponent_;    
+    
+    numerator = 0;
+    exponent = 0;
+    IntT denominator {};
+    
+    do
+    {
+        // 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);
+    
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::operator double() const
+{
+    constexpr IntT one = static_cast<IntT>(1);
+    IntT denominator = times_power_of_2(one, exponent_);
+    return static_cast<double>(numerator_) / denominator;
+}
+
+
+template<class IntT>
+IntT PowerOfTwoApprox<IntT>::GetNumerator() const
+{
+    return numerator_;
+}
+
+
+template<class IntT>
+int PowerOfTwoApprox<IntT>::GetExponent() const
+{
+    return exponent_;
+}
+
+
+enum class RoundToInteger { no, yes };
+
+
+class TestDisplay
+{
+public:
+    
+    //! Constructor which sets the only the resolution (i.e. the maximum index upon which error is defined).
+    TestDisplay(int resolution);
+    
+    //! To make TestDisplay an abstract class.
+    virtual ~TestDisplay();
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits) const = 0;
+
+
+protected:
+    
+   /*!
+    * \brief  Print a line with information about error.
+    *
+    * \param[in] optional_string1 String that might appear just after the "[With N bits]:".
+    * \param[in] optional_string2 String that might appear just before the "[error = ...]".
+    * \param[in] do_round_to_integer If yes, the exact result is approximated as an integer.
+    */
+    template<class IntT>
+   void PrintLine(int Nbits, double exact, double approx,
+                  std::string optional_string1 = "", std::string optional_string2 = "",
+                  RoundToInteger do_round_to_integer = RoundToInteger::no) const;
+                  
+private:
+    
+    //! Resolution.
+    const int resolution_;
+  
+};
+
+
+TestDisplay::TestDisplay(int resolution)
+: resolution_(resolution)
+{ }
+
+
+TestDisplay::~TestDisplay() = default;
+
+
+void TestDisplay::operator()(int Nbits) const
+{
+    static_cast<void>(Nbits); // neutralize warning about unused argument at no runtime cost.
+}
+
+
+template<class IntT>
+void TestDisplay::PrintLine(int Nbits, double exact, double approx,
+                            std::string optional_string1, std::string optional_string2,
+                            RoundToInteger do_round_to_integer) const
+{
+    IntT error = round_as_int<IntT>(resolution_ * std::fabs(exact - approx) / exact);
+ 
+    std::cout << "[With " << Nbits << " bits]: " << optional_string1
+        << (do_round_to_integer == RoundToInteger::yes ? round_as_int<IntT>(exact) : exact)  << " ~ " << approx
+        << optional_string2
+        << "  [error = " << error << "/" << resolution_ << "]" 
+        << std::endl;    
+}
+
+
+class TestDisplayPowerOfTwoApprox : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox(int resolution);
+    
+    //! Destructor
+    virtual ~TestDisplayPowerOfTwoApprox() override;
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits)const override = 0;
+    
+protected:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value) const;
+    
+};
+
+
+TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
+: TestDisplay(resolution)
+{ }    
+
+TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
+
+
+void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
+{
+    using integer_type = long;
+    PowerOfTwoApprox<integer_type> approximation(Nbits, value);
+
+    const double approx = static_cast<double>(approximation);
+    
+    std::ostringstream oconv;
+    oconv << "  (" << approximation << ")";    
+    PrintLine<integer_type>(Nbits, value, approx, "", oconv.str());
+}
+
+
+class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox065(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox065() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
+: TestDisplayPowerOfTwoApprox(resolution)
+{ }
+
+
+TestDisplayPowerOfTwoApprox065::~TestDisplayPowerOfTwoApprox065() = default;
+
+
+void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
+{
+    Display(Nbits, 0.65);    
+}
+
+
+class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox035(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox035() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
+: TestDisplayPowerOfTwoApprox(resolution)
+{ }
+
+TestDisplayPowerOfTwoApprox035::~TestDisplayPowerOfTwoApprox035() = default;
+
+
+void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
+{
+    Display(Nbits, 0.35);    
+}
+
+
+template<class IntT>
+class TestDisplayMultiply : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    explicit TestDisplayMultiply(int resolution);
+    
+    //! To make the class a concrete one.
+    virtual ~TestDisplayMultiply() override;
+    
+    
+    //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+        
+private:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
+    
+};
+
+
+template<class IntT>
+TestDisplayMultiply<IntT>::TestDisplayMultiply(int resolution)
+: TestDisplay(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayMultiply<IntT>::~TestDisplayMultiply() = default;
+
+
+template<class IntT>
+void TestDisplayMultiply<IntT>::operator()(int Nbits) const
+{
+    Display(Nbits, 0.65, static_cast<IntT>(3515), 0.35, static_cast<IntT>(4832));
+}
+
+
+template<class IntT>
+void TestDisplayMultiply<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
+{
+    double exact = value1 * coefficient1 + value2 * coefficient2;
+    
+    PowerOfTwoApprox<IntT> approximation1(Nbits, value1);
+    PowerOfTwoApprox<IntT> approximation2(Nbits, value2);    
+    
+    IntT approx = approximation1 * coefficient1  + coefficient2 * approximation2;
+    
+    std::ostringstream oconv;
+    oconv << value1 << " * " << coefficient1 << " + " << value2 << " * " << coefficient2 << " = ";
+    
+    PrintLine<IntT>(Nbits, exact, static_cast<double>(approx), oconv.str(), "", RoundToInteger::yes);
+}
+
+
+//! Function for error handling. We will see later how to fulfill the same functionality more properly.
+[[noreturn]] void error(std::string explanation)
+{
+    std::cout << "ERROR: " << explanation << std::endl;
+    exit(EXIT_FAILURE);
+}
+
+
+class TestDisplayContainer
+{
+public:
+    
+    //! Constructor.
+    TestDisplayContainer(std::size_t capacity);
+    
+    //! Destructor.
+    ~TestDisplayContainer();
+
+    //! Add a new test_display_register.
+    //! At each call, the item to be registered is put at the first available position and internal current_position_
+    //! is incremented. If the end-user attempts to register more than three items, the error() function is called.
+    void Register(TestDisplay* test_display);
+    
+    //! Accessor to the i-th object in the container.
+    const TestDisplay& operator[](std::size_t i) const;
+    
+    //! Get the number of elements actually stored in the class (nullptr don't count).
+    std::size_t GetSize() const;
+    
+    
+private:
+    
+    //! Get the maximal number of elements that might be stored in the container.
+    std::size_t GetCapacity() const;
+    
+private:    
+    
+    //! Maximum number of items that might be registered in the container.
+    const std::size_t capacity_;
+    
+    //! List of all known `TestDisplay` objects.
+    TestDisplay** list_;
+    
+    //! Index to place the next register object. If '3', no more object may be registered.
+    std::size_t current_position_ {};
+
+};
+
+
+TestDisplayContainer::TestDisplayContainer(std::size_t capacity)
+: capacity_(capacity)
+{
+    list_ = new TestDisplay*[capacity];
+    
+    for (auto i = 0ul; i < capacity; ++i)
+        list_[i] = nullptr;
+}
+
+
+TestDisplayContainer::~TestDisplayContainer()
+{
+    for (auto i = 0ul; i < capacity_; ++i)
+        delete list_[i];
+    
+    delete[] list_; // don't forget the [] to delete an array!
+}
+
+
+void TestDisplayContainer::Register(TestDisplay* test_display)
+{
+    if (current_position_ >= capacity_)
+        error("TestDisplayContainer is already full; impossible to register a new element!");
+    
+    list_[current_position_] = test_display;
+    ++current_position_;
+}
+
+
+const TestDisplay& TestDisplayContainer::operator[](std::size_t i) const
+{
+    if (i >= GetCapacity())
+        error("You try to access an element out of bounds!");
+    
+    if (list_[i] == nullptr) // equivalent to i >= GetSize()
+        error("You try to access an element that was never initialized!");
+    
+    return *list_[i];    
+}
+
+
+std::size_t TestDisplayContainer::GetCapacity() const
+{
+    return capacity_;
+}
+
+
+std::size_t TestDisplayContainer::GetSize() const
+{
+    return current_position_;
+}
+
+
+//! For each container stored, loop oover all those bits and print the result on screen.
+void loop(int initial_Nbit, int final_Nbit, int increment_Nbit, const TestDisplayContainer& container)
+{
+    for (auto i = 0ul; i < container.GetSize(); ++i)
+    {
+        decltype(auto) current_test_display = container[i];
+            
+        for (int Nbits = initial_Nbit; Nbits <= final_Nbit; Nbits += increment_Nbit)
+            current_test_display(Nbits);
+        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      
+
+    TestDisplayContainer container(3);
+    
+    using integer_type = long;
+    
+    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
+    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
+    container.Register(new TestDisplayMultiply<integer_type>(10000));
+    
+    loop(4, 32, 4, container);
+    
+    return EXIT_SUCCESS;
+}
+
diff --git a/TP/4-Templates/Solution/exercice33.cpp b/TP/4-Templates/Solution/exercice33.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..11ca7c283abc9b2fc163740e47dfdb9ef90fd88a
--- /dev/null
+++ b/TP/4-Templates/Solution/exercice33.cpp
@@ -0,0 +1,536 @@
+#include <iostream>
+#include <sstream> // for std::ostringstream
+#include <string>
+#include <cmath> // for std::round
+
+
+//! Returns `number` * (2 ^ `exponent`) 
+template<class IntT>
+IntT times_power_of_2(IntT number, int exponent)
+{
+    constexpr IntT two = static_cast<IntT>(2);
+    
+    while (exponent > 0)
+    { 
+        number *= two; 
+        exponent -= 1; 
+    }
+    while (exponent < 0)
+    { 
+        number /= two;
+        exponent += 1 ; 
+    }
+    
+    return number;
+}
+    
+
+//! Round to `x` the nearest integer.
+template<class IntT>
+IntT round_as_int(double x)
+{
+    return static_cast<IntT>(std::round(x));
+}
+
+
+// Maximum integer that might be represented with `Nbits` bits.
+template<class IntT>
+IntT max_int(int Nbits)
+{ 
+    constexpr IntT one = static_cast<IntT>(1);
+    return (times_power_of_2(one, Nbits) - one);
+}
+
+
+//! Class to group the two integers used in the approximation we define.
+template<class IntT>
+class PowerOfTwoApprox
+{
+public:
+    
+    //! Compute the best possible approximation of `value` with `Nbits`
+    PowerOfTwoApprox(int Nbits, double value);
+
+    //! \return The approximation as a floating point.
+    explicit operator double() const;
+    
+    //! Accessor to numerator.
+    IntT GetNumerator() const;
+    
+    //! Accessor to exponent.
+    int GetExponent() const;
+    
+ 
+        
+private:
+        
+    IntT numerator_ {};
+    int exponent_ {};    
+};  
+
+
+template<class IntT>
+std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approximation)
+{
+    out << approximation.GetNumerator() << "/2^" << approximation.GetExponent();
+    return out;
+}
+
+
+/*! 
+ * \brief Multiply the approximate representation by an integer. 
+ * 
+ * \param[in] coefficient Integer coefficient by which the object is multiplied.
+ * 
+ * \return An approximate integer result of the multiplication.
+ */
+template<class IntT>
+IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
+{
+  return times_power_of_2(approx.GetNumerator() * coefficient, -approx.GetExponent());
+}
+ 
+
+template<class IntT> 
+IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
+{
+  return coefficient * approx;
+}
+
+
+//! 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!
+//! Note: could be put in the struct... but may be kept a free function as well! We will see much later
+//! the anonymous namespace, in which I would typically put such a free function.
+template<class IntT>
+void helper_compute_power_of_2_approx(double value, int exponent, IntT& numerator, IntT& denominator)
+{
+    constexpr IntT one = static_cast<IntT>(1);
+    denominator = times_power_of_2(one, exponent);   
+    numerator = round_as_int<IntT>(value * denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::PowerOfTwoApprox(int Nbits, double value)
+{
+    IntT max_numerator = max_int<IntT>(Nbits);
+    
+    auto& numerator = numerator_;
+    int& exponent = exponent_;    
+    
+    numerator = 0;
+    exponent = 0;
+    IntT denominator {};
+    
+    do
+    {
+        // 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);
+    
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::operator double() const
+{
+    constexpr IntT one = static_cast<IntT>(1);
+    IntT denominator = times_power_of_2(one, exponent_);
+    return static_cast<double>(numerator_) / denominator;
+}
+
+
+template<class IntT>
+IntT PowerOfTwoApprox<IntT>::GetNumerator() const
+{
+    return numerator_;
+}
+
+
+template<class IntT>
+int PowerOfTwoApprox<IntT>::GetExponent() const
+{
+    return exponent_;
+}
+
+
+enum class RoundToInteger { no, yes };
+
+
+class TestDisplay
+{
+public:
+    
+    //! Constructor which sets the only the resolution (i.e. the maximum index upon which error is defined).
+    TestDisplay(int resolution);
+    
+    //! To make TestDisplay an abstract class.
+    virtual ~TestDisplay();
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits) const = 0;
+
+
+protected:
+    
+   /*!
+    * \brief  Print a line with information about error.
+    *
+    * \param[in] optional_string1 String that might appear just after the "[With N bits]:".
+    * \param[in] optional_string2 String that might appear just before the "[error = ...]".
+    * \param[in] do_round_to_integer If yes, the exact result is approximated as an integer.
+    */
+    template<class IntT>
+   void PrintLine(int Nbits, double exact, double approx,
+                  std::string optional_string1 = "", std::string optional_string2 = "",
+                  RoundToInteger do_round_to_integer = RoundToInteger::no) const;
+                  
+private:
+    
+    //! Resolution.
+    const int resolution_;
+  
+};
+
+
+TestDisplay::TestDisplay(int resolution)
+: resolution_(resolution)
+{ }
+
+
+TestDisplay::~TestDisplay() = default;
+
+
+void TestDisplay::operator()(int Nbits) const
+{
+    static_cast<void>(Nbits); // neutralize warning about unused argument at no runtime cost.
+}
+
+
+template<class IntT>
+void TestDisplay::PrintLine(int Nbits, double exact, double approx,
+                            std::string optional_string1, std::string optional_string2,
+                            RoundToInteger do_round_to_integer) const
+{
+    IntT error = round_as_int<IntT>(resolution_ * std::fabs(exact - approx) / exact);
+ 
+    std::cout << "[With " << Nbits << " bits]: " << optional_string1
+        << (do_round_to_integer == RoundToInteger::yes ? round_as_int<IntT>(exact) : exact)  << " ~ " << approx
+        << optional_string2
+        << "  [error = " << error << "/" << resolution_ << "]" 
+        << std::endl;    
+}
+
+
+template<class IntT>
+class TestDisplayPowerOfTwoApprox : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox(int resolution);
+    
+    //! Destructor
+    virtual ~TestDisplayPowerOfTwoApprox() override;
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits)const override = 0;
+    
+protected:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value) const;
+    
+};
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox<IntT>::TestDisplayPowerOfTwoApprox(int resolution)
+: TestDisplay(resolution)
+{ }    
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox<IntT>::~TestDisplayPowerOfTwoApprox() = default;
+
+
+template<class IntT>
+void TestDisplayPowerOfTwoApprox<IntT>::Display(int Nbits, double value) const
+{
+    PowerOfTwoApprox<IntT> approximation(Nbits, value);
+
+    const double approx = static_cast<double>(approximation);
+    
+    std::ostringstream oconv;
+    oconv << "  (" << approximation << ")";    
+    PrintLine<IntT>(Nbits, value, approx, "", oconv.str());
+}
+
+
+template<class IntT>
+class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox<IntT>
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox065(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox065() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox065<IntT>::TestDisplayPowerOfTwoApprox065(int resolution)
+: TestDisplayPowerOfTwoApprox<IntT>(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox065<IntT>::~TestDisplayPowerOfTwoApprox065() = default;
+
+
+template<class IntT>
+void TestDisplayPowerOfTwoApprox065<IntT>::operator()(int Nbits) const
+{
+    this->Display(Nbits, 0.65);    
+}
+
+
+template<class IntT>
+class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox<IntT>
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox035(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox035() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox035<IntT>::TestDisplayPowerOfTwoApprox035(int resolution)
+: TestDisplayPowerOfTwoApprox<IntT>(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox035<IntT>::~TestDisplayPowerOfTwoApprox035() = default;
+
+
+template<class IntT>
+void TestDisplayPowerOfTwoApprox035<IntT>::operator()(int Nbits) const
+{
+    this->Display(Nbits, 0.35);    
+}
+
+
+template<class IntT>
+class TestDisplayMultiply : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    explicit TestDisplayMultiply(int resolution);
+    
+    //! To make the class a concrete one.
+    virtual ~TestDisplayMultiply() override;
+    
+    
+    //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+        
+private:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
+    
+};
+
+
+template<class IntT>
+TestDisplayMultiply<IntT>::TestDisplayMultiply(int resolution)
+: TestDisplay(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayMultiply<IntT>::~TestDisplayMultiply() = default;
+
+
+template<class IntT>
+void TestDisplayMultiply<IntT>::operator()(int Nbits) const
+{
+    Display(Nbits, 0.65, static_cast<IntT>(3515), 0.35, static_cast<IntT>(4832));
+}
+
+
+template<class IntT>
+void TestDisplayMultiply<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
+{
+    double exact = value1 * coefficient1 + value2 * coefficient2;
+    
+    PowerOfTwoApprox<IntT> approximation1(Nbits, value1);
+    PowerOfTwoApprox<IntT> approximation2(Nbits, value2);    
+    
+    IntT approx = approximation1 * coefficient1 + coefficient2 * approximation2;
+    
+    std::ostringstream oconv;
+    oconv << value1 << " * " << coefficient1 << " + " << value2 << " * " << coefficient2 << " = ";
+    
+    PrintLine<IntT>(Nbits, exact, static_cast<double>(approx), oconv.str(), "", RoundToInteger::yes);
+}
+
+
+//! Function for error handling. We will see later how to fulfill the same functionality more properly.
+[[noreturn]] void error(std::string explanation)
+{
+    std::cout << "ERROR: " << explanation << std::endl;
+    exit(EXIT_FAILURE);
+}
+
+
+class TestDisplayContainer
+{
+public:
+    
+    //! Constructor.
+    TestDisplayContainer(std::size_t capacity);
+    
+    //! Destructor.
+    ~TestDisplayContainer();
+
+    //! Add a new test_display_register.
+    //! At each call, the item to be registered is put at the first available position and internal current_position_
+    //! is incremented. If the end-user attempts to register more than three items, the error() function is called.
+    void Register(TestDisplay* test_display);
+    
+    //! Accessor to the i-th object in the container.
+    const TestDisplay& operator[](std::size_t i) const;
+    
+    //! Get the number of elements actually stored in the class (nullptr don't count).
+    std::size_t GetSize() const;
+    
+    
+private:
+    
+    //! Get the maximal number of elements that might be stored in the container.
+    std::size_t GetCapacity() const;
+    
+private:    
+    
+    //! Maximum number of items that might be registered in the container.
+    const std::size_t capacity_;
+    
+    //! List of all known `TestDisplay` objects.
+    TestDisplay** list_;
+    
+    //! Index to place the next register object. If '3', no more object may be registered.
+    std::size_t current_position_ {};
+
+};
+
+
+TestDisplayContainer::TestDisplayContainer(std::size_t capacity)
+: capacity_(capacity)
+{
+    list_ = new TestDisplay*[capacity];
+    
+    for (auto i = 0ul; i < capacity; ++i)
+        list_[i] = nullptr;
+}
+
+
+TestDisplayContainer::~TestDisplayContainer()
+{
+    for (auto i = 0ul; i < capacity_; ++i)
+        delete list_[i];
+    
+    delete[] list_; // don't forget the [] to delete an array!
+}
+
+
+void TestDisplayContainer::Register(TestDisplay* test_display)
+{
+    if (current_position_ >= capacity_)
+        error("TestDisplayContainer is already full; impossible to register a new element!");
+    
+    list_[current_position_] = test_display;
+    ++current_position_;
+}
+
+
+const TestDisplay& TestDisplayContainer::operator[](std::size_t i) const
+{
+    if (i >= GetCapacity())
+        error("You try to access an element out of bounds!");
+    
+    if (list_[i] == nullptr) // equivalent to i >= GetSize()
+        error("You try to access an element that was never initialized!");
+    
+    return *list_[i];    
+}
+
+
+std::size_t TestDisplayContainer::GetCapacity() const
+{
+    return capacity_;
+}
+
+
+std::size_t TestDisplayContainer::GetSize() const
+{
+    return current_position_;
+}
+
+
+//! For each container stored, loop oover all those bits and print the result on screen.
+void loop(int initial_Nbit, int final_Nbit, int increment_Nbit, const TestDisplayContainer& container)
+{
+    for (auto i = 0ul; i < container.GetSize(); ++i)
+    {
+        decltype(auto) current_test_display = container[i];
+            
+        for (int Nbits = initial_Nbit; Nbits <= final_Nbit; Nbits += increment_Nbit)
+            current_test_display(Nbits);
+        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      
+
+    TestDisplayContainer container(3);
+    
+    using integer_type = long;
+    
+    container.Register(new TestDisplayPowerOfTwoApprox065<integer_type>(100000000));
+    container.Register(new TestDisplayPowerOfTwoApprox035<integer_type>(100000000));
+    container.Register(new TestDisplayMultiply<integer_type>(1000000));
+    
+    loop(4, 32, 4, container);
+    
+    return EXIT_SUCCESS;
+}
+
diff --git a/TP/4-Templates/Solution/exercice34.cpp b/TP/4-Templates/Solution/exercice34.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1becc146d1b94ec818c5f560f6ff5c8a9a16b2a4
--- /dev/null
+++ b/TP/4-Templates/Solution/exercice34.cpp
@@ -0,0 +1,540 @@
+#include <iostream>
+#include <sstream> // for std::ostringstream
+#include <string>
+#include <cmath> // for std::round
+
+
+//! Returns `number` * (2 ^ `exponent`) 
+template<class IntT>
+IntT times_power_of_2(IntT number, int exponent)
+{
+    constexpr IntT two = static_cast<IntT>(2);
+    
+    while (exponent > 0)
+    { 
+        number *= two; 
+        exponent -= 1; 
+    }
+    while (exponent < 0)
+    { 
+        number /= two;
+        exponent += 1 ; 
+    }
+    
+    return number;
+}
+    
+
+//! Round to `x` the nearest integer.
+template<class IntT>
+IntT round_as_int(double x)
+{
+    return static_cast<IntT>(std::round(x));
+}
+
+
+// Maximum integer that might be represented with `Nbits` bits.
+template<class IntT>
+IntT max_int(int Nbits)
+{ 
+    constexpr IntT one = static_cast<IntT>(1);
+    return (times_power_of_2(one, Nbits) - one);
+}
+
+
+//! Class to group the two integers used in the approximation we define.
+template<class IntT>
+class PowerOfTwoApprox
+{
+public:
+    
+    //! Compute the best possible approximation of `value` with `Nbits`
+    PowerOfTwoApprox(int Nbits, double value);
+
+    //! \return The approximation as a floating point.
+    explicit operator double() const;
+    
+    //! Accessor to numerator.
+    IntT GetNumerator() const;
+    
+    //! Accessor to exponent.
+    int GetExponent() const;
+    
+ 
+        
+private:
+        
+    IntT numerator_ {};
+    int exponent_ {};    
+};  
+
+
+template<class IntT>
+std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approximation)
+{
+    out << approximation.GetNumerator() << "/2^" << approximation.GetExponent();
+    return out;
+}
+
+
+/*! 
+ * \brief Multiply the approximate representation by an integer. 
+ * 
+ * \param[in] coefficient Integer coefficient by which the object is multiplied.
+ * 
+ * \return An approximate integer result of the multiplication.
+ */
+template<class IntT>
+IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
+{
+  return times_power_of_2(approx.GetNumerator() * coefficient, -approx.GetExponent());
+}
+ 
+
+template<class IntT> 
+IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
+{
+  return coefficient * approx;
+}
+
+
+//! 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!
+//! Note: could be put in the struct... but may be kept a free function as well! We will see much later
+//! the anonymous namespace, in which I would typically put such a free function.
+template<class IntT>
+void helper_compute_power_of_2_approx(double value, int exponent, IntT& numerator, IntT& denominator)
+{
+    constexpr IntT one = static_cast<IntT>(1);
+    denominator = times_power_of_2(one, exponent);   
+    numerator = round_as_int<IntT>(value * denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::PowerOfTwoApprox(int Nbits, double value)
+{
+    IntT max_numerator = max_int<IntT>(Nbits);
+    
+    auto& numerator = numerator_;
+    int& exponent = exponent_;    
+    
+    numerator = 0;
+    exponent = 0;
+    IntT denominator {};
+    
+    do
+    {
+        // 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);
+    
+    helper_compute_power_of_2_approx(value, --exponent, numerator, denominator);
+}
+
+
+template<class IntT>
+PowerOfTwoApprox<IntT>::operator double() const
+{
+    constexpr IntT one = static_cast<IntT>(1);
+    IntT denominator = times_power_of_2(one, exponent_);
+    return static_cast<double>(numerator_) / denominator;
+}
+
+
+template<class IntT>
+IntT PowerOfTwoApprox<IntT>::GetNumerator() const
+{
+    return numerator_;
+}
+
+
+template<class IntT>
+int PowerOfTwoApprox<IntT>::GetExponent() const
+{
+    return exponent_;
+}
+
+
+enum class RoundToInteger { no, yes };
+
+
+class TestDisplay
+{
+public:
+    
+    //! Constructor which sets the only the resolution (i.e. the maximum index upon which error is defined).
+    TestDisplay(int resolution);
+    
+    //! To make TestDisplay an abstract class.
+    virtual ~TestDisplay();
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits) const = 0;
+
+
+protected:
+    
+   /*!
+    * \brief  Print a line with information about error.
+    *
+    * \param[in] optional_string1 String that might appear just after the "[With N bits]:".
+    * \param[in] optional_string2 String that might appear just before the "[error = ...]".
+    * \param[in] do_round_to_integer If yes, the exact result is approximated as an integer.
+    */
+    template<class IntT>
+   void PrintLine(int Nbits, double exact, double approx,
+                  std::string optional_string1 = "", std::string optional_string2 = "",
+                  RoundToInteger do_round_to_integer = RoundToInteger::no) const;
+                  
+private:
+    
+    //! Resolution.
+    const int resolution_;
+  
+};
+
+
+TestDisplay::TestDisplay(int resolution)
+: resolution_(resolution)
+{ }
+
+
+TestDisplay::~TestDisplay() = default;
+
+
+void TestDisplay::operator()(int Nbits) const
+{
+    static_cast<void>(Nbits); // neutralize warning about unused argument at no runtime cost.
+}
+
+
+template<class IntT>
+void TestDisplay::PrintLine(int Nbits, double exact, double approx,
+                            std::string optional_string1, std::string optional_string2,
+                            RoundToInteger do_round_to_integer) const
+{
+    IntT error = round_as_int<IntT>(resolution_ * std::fabs(exact - approx) / exact);
+ 
+    std::cout << "[With " << Nbits << " bits]: " << optional_string1
+        << (do_round_to_integer == RoundToInteger::yes ? round_as_int<IntT>(exact) : exact)  << " ~ " << approx
+        << optional_string2
+        << "  [error = " << error << "/" << resolution_ << "]" 
+        << std::endl;    
+}
+
+
+template<class IntT>
+class TestDisplayPowerOfTwoApprox : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox(int resolution);
+    
+    //! Destructor
+    virtual ~TestDisplayPowerOfTwoApprox() override;
+    
+    //! Pure virtual method Do().
+    virtual void operator()(int Nbits)const override = 0;
+    
+protected:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value) const;
+    
+};
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox<IntT>::TestDisplayPowerOfTwoApprox(int resolution)
+: TestDisplay(resolution)
+{ }    
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox<IntT>::~TestDisplayPowerOfTwoApprox() = default;
+
+
+template<class IntT>
+void TestDisplayPowerOfTwoApprox<IntT>::Display(int Nbits, double value) const
+{
+    PowerOfTwoApprox<IntT> approximation(Nbits, value);
+
+    const double approx = static_cast<double>(approximation);
+    
+    std::ostringstream oconv;
+    oconv << "  (" << approximation << ")";    
+    PrintLine<IntT>(Nbits, value, approx, "", oconv.str());
+}
+
+
+template<class IntT>
+class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox<IntT>
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox065(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox065() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox065<IntT>::TestDisplayPowerOfTwoApprox065(int resolution)
+: TestDisplayPowerOfTwoApprox<IntT>(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox065<IntT>::~TestDisplayPowerOfTwoApprox065() = default;
+
+
+template<class IntT>
+void TestDisplayPowerOfTwoApprox065<IntT>::operator()(int Nbits) const
+{
+    this->Display(Nbits, 0.65);    
+}
+
+
+template<class IntT>
+class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox<IntT>
+{
+public:
+    
+    //! Constructor.
+    TestDisplayPowerOfTwoApprox035(int resolution);
+    
+    //! Destructor,
+    ~TestDisplayPowerOfTwoApprox035() override;
+    
+     //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+
+};
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox035<IntT>::TestDisplayPowerOfTwoApprox035(int resolution)
+: TestDisplayPowerOfTwoApprox<IntT>(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayPowerOfTwoApprox035<IntT>::~TestDisplayPowerOfTwoApprox035() = default;
+
+
+template<class IntT>
+void TestDisplayPowerOfTwoApprox035<IntT>::operator()(int Nbits) const
+{
+    this->Display(Nbits, 0.35);    
+}
+
+
+template<class IntT>
+class TestDisplayMultiply : public TestDisplay
+{
+public:
+    
+    //! Constructor.
+    explicit TestDisplayMultiply(int resolution);
+    
+    //! To make the class a concrete one.
+    virtual ~TestDisplayMultiply() override;
+    
+    
+    //! Display the output for the chosen `Nbits`.
+    void operator()(int Nbits)const override;
+        
+private:
+    
+    //! Method in charge of the actual display.
+    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
+    
+};
+
+
+template<class IntT>
+TestDisplayMultiply<IntT>::TestDisplayMultiply(int resolution)
+: TestDisplay(resolution)
+{ }
+
+
+template<class IntT>
+TestDisplayMultiply<IntT>::~TestDisplayMultiply() = default;
+
+
+template<class IntT>
+void TestDisplayMultiply<IntT>::operator()(int Nbits) const
+{
+    Display(Nbits, 0.65, static_cast<IntT>(3515), 0.35, static_cast<IntT>(4832));
+}
+
+
+template<class IntT>
+void TestDisplayMultiply<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
+{
+    double exact = value1 * coefficient1 + value2 * coefficient2;
+    
+    PowerOfTwoApprox<IntT> approximation1(Nbits, value1);
+    PowerOfTwoApprox<IntT> approximation2(Nbits, value2);    
+    
+    IntT approx = approximation1 * coefficient1 + coefficient2 * approximation2;
+    
+    std::ostringstream oconv;
+    oconv << value1 << " * " << coefficient1 << " + " << value2 << " * " << coefficient2 << " = ";
+    
+    PrintLine<IntT>(Nbits, exact, static_cast<double>(approx), oconv.str(), "", RoundToInteger::yes);
+}
+
+
+//! Function for error handling. We will see later how to fulfill the same functionality more properly.
+[[noreturn]] void error(std::string explanation)
+{
+    std::cout << "ERROR: " << explanation << std::endl;
+    exit(EXIT_FAILURE);
+}
+
+
+template<std::size_t CapacityN>
+class TestDisplayContainer
+{
+public:
+    
+    //! Constructor.
+    TestDisplayContainer();
+    
+    //! Destructor.
+    ~TestDisplayContainer();
+
+    //! Add a new test_display_register.
+    //! At each call, the item to be registered is put at the first available position and internal current_position_
+    //! is incremented. If the end-user attempts to register more than three items, the error() function is called.
+    void Register(TestDisplay* test_display);
+    
+    //! Accessor to the i-th object in the container.
+    const TestDisplay& operator[](std::size_t i) const;
+    
+    //! Get the number of elements actually stored in the class (nullptr don't count).
+    std::size_t GetSize() const;
+    
+    
+private:
+    
+    //! Get the maximal number of elements that might be stored in the container.
+    constexpr std::size_t GetCapacity() const;
+    
+private:    
+    
+    //! List of all known `TestDisplay` objects.
+    TestDisplay** list_;
+    
+    //! Index to place the next register object. If '3', no more object may be registered.
+    std::size_t current_position_ {};
+
+};
+
+
+template<std::size_t CapacityN>
+TestDisplayContainer<CapacityN>::TestDisplayContainer()
+{
+    list_ = new TestDisplay*[CapacityN];
+    
+    for (auto i = 0ul; i < CapacityN; ++i)
+        list_[i] = nullptr;
+}
+
+
+template<std::size_t CapacityN>
+TestDisplayContainer<CapacityN>::~TestDisplayContainer()
+{
+    for (auto i = 0ul; i < CapacityN; ++i)
+        delete list_[i];
+    
+    delete[] list_; // don't forget the [] to delete an array!
+}
+
+
+template<std::size_t CapacityN>
+void TestDisplayContainer<CapacityN>::Register(TestDisplay* test_display)
+{
+    if (current_position_ >= CapacityN)
+        error("TestDisplayContainer is already full; impossible to register a new element!");
+    
+    list_[current_position_] = test_display;
+    ++current_position_;
+}
+
+
+template<std::size_t CapacityN>
+const TestDisplay& TestDisplayContainer<CapacityN>::operator[](std::size_t i) const
+{
+    if (i >= GetCapacity())
+        error("You try to access an element out of bounds!");
+    
+    if (list_[i] == nullptr) // equivalent to i >= GetSize()
+        error("You try to access an element that was never initialized!");
+    
+    return *list_[i];    
+}
+
+
+template<std::size_t CapacityN>
+constexpr std::size_t TestDisplayContainer<CapacityN>::GetCapacity() const
+{
+    return CapacityN;
+}
+
+
+template<std::size_t CapacityN>
+std::size_t TestDisplayContainer<CapacityN>::GetSize() const
+{
+    return current_position_;
+}
+
+
+//! For each container stored, loop oover all those bits and print the result on screen.
+template<std::size_t CapacityN>
+void loop(int initial_Nbit, int final_Nbit, int increment_Nbit, const TestDisplayContainer<CapacityN>& container)
+{
+    for (auto i = 0ul; i < container.GetSize(); ++i)
+    {
+        decltype(auto) current_test_display = container[i];
+            
+        for (int Nbits = initial_Nbit; Nbits <= final_Nbit; Nbits += increment_Nbit)
+            current_test_display(Nbits);
+        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      
+
+    TestDisplayContainer<3> container;
+    
+    using integer_type = long;
+    
+    container.Register(new TestDisplayPowerOfTwoApprox065<integer_type>(100000000));
+    container.Register(new TestDisplayPowerOfTwoApprox035<integer_type>(100000000));
+    container.Register(new TestDisplayMultiply<integer_type>(1000000));
+    
+    loop(4, 32, 4, container);
+    
+    return EXIT_SUCCESS;
+}
+
diff --git a/TP/4-Templates/Solution/exercice37.cpp b/TP/4-Templates/Solution/exercice37.cpp
deleted file mode 100644
index f1f79d312c33af698c843e8f72472175c2d3f65d..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice37.cpp
+++ /dev/null
@@ -1,499 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent)
-{
-    while (exponent > 0)
-    { 
-        number *= 2; 
-        exponent -= 1; 
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    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);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend int operator*(const PowerOfTwoApprox<IntU>& approx, int coefficient);
-
-    template<class IntU>    
-    friend int operator*(int coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    int denominator {};
-    
-    int max_numerator = max_int(Nbits);
-    
-    do
-    {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
-    }
-    while (numerator <= max_numerator);
-    
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    int denominator = times_power_of_2(1, exponent_); 
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-int operator*(const PowerOfTwoApprox<IntT>& approx, int coefficient)
-{
-    return times_power_of_2(approx.Numerator() * coefficient, -approx.Exponent());
-}
-
-
-template<class IntT>
-int operator*(int coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << approx.Numerator() << "/2^" << approx.Exponent();
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: " << after_bit_string
-        << exact << " ~ " << approx
-        << before_error
-        << "  [error = " << error << "/" << resolution_ << "]" 
-        << std::endl;    
-}
-
-
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-
-TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
-
-
-void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
-{
-    PowerOfTwoApprox<int> approx(Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(Nbits, value, double_approx, "", oconv.str());
-}
-
-
-TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65);
-}
-
-
-void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
-{
-    Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, int coefficient1, double value2, int coefficient2) const;
-
-};
-
-
-TestDisplaySum::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-void TestDisplaySum::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-void TestDisplaySum::Display(int Nbits, double value1, int coefficient1, double value2, int coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    PowerOfTwoApprox<int> approx1(Nbits, value1);
-    PowerOfTwoApprox<int> approx2(Nbits, value2);
-
-    int approx = coefficient1 * approx1 + coefficient2 * approx2;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    TestDisplayContainer container(3);
-    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
-    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
-    container.Register(new TestDisplaySum(1000000));
-    
-    loop(4, 16, 4, container);
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice38.cpp b/TP/4-Templates/Solution/exercice38.cpp
deleted file mode 100644
index 2295bed6d7ddab5266ac0e360f530700560e5900..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice38.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(int number, int exponent)
-{
-    while (exponent > 0)
-    { 
-        number *= 2; 
-        exponent -= 1; 
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    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);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    int denominator {};
-    
-    int max_numerator = max_int(Nbits);
-    
-    do
-    {
-        ++exponent;
-        denominator = times_power_of_2(1, exponent);   
-        numerator = round_as_int(value * denominator);
-    }
-    while (numerator <= max_numerator);
-    
-    --exponent;
-    denominator = times_power_of_2(1, exponent); 
-    numerator = round_as_int(value * denominator);
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    int denominator = times_power_of_2(1, exponent_); 
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    return times_power_of_2(approx.Numerator() * coefficient, -approx.Exponent());
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << approx.Numerator() << "/2^" << approx.Exponent();
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: " << after_bit_string
-        << exact << " ~ " << approx
-        << before_error
-        << "  [error = " << error << "/" << resolution_ << "]" 
-        << std::endl;    
-}
-
-
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-
-TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
-
-
-void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
-{
-    PowerOfTwoApprox<short> approx(Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(Nbits, value, double_approx, "", oconv.str());
-}
-
-
-TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65);
-}
-
-
-void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
-{
-    Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    PowerOfTwoApprox<IntT> approx1(Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(Nbits, value2);
-
-    IntT approx = coefficient1 * approx1 + coefficient2 * approx2;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    TestDisplayContainer container(3);
-    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
-    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
-    container.Register(new TestDisplaySum<short>(1000000));
-    
-    loop(4, 16, 4, container);
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice39.cpp b/TP/4-Templates/Solution/exercice39.cpp
deleted file mode 100644
index 95b892e3669d629d017bf542952ed88544a08f5d..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice39.cpp
+++ /dev/null
@@ -1,570 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-#include <limits>
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-int times_power_of_2(bool& is_overflow, int number, int exponent)
-{
-    constexpr auto half_max = std::numeric_limits<int>::max() / 2;
-    
-    while (exponent > 0)
-    { 
-        if (number < half_max)
-        {
-            number *= 2; 
-            exponent -= 1; 
-        }
-        else
-        {
-            is_overflow = true;
-            std::cerr << "Overflow in times_power_of_2 with number = " << number << " and exponent = " 
-                << exponent << std::endl;
-            return std::numeric_limits<int>::lowest(); // arbitrary value
-        }
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    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(bool& is_overflow, int Nbits)
-{ 
-    return (times_power_of_2(is_overflow, 1, Nbits) - 1);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(bool& is_overflow, int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(bool& is_overflow, int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    int denominator {};
-    
-    auto max_numerator = max_int(is_overflow, Nbits);
-    
-    int new_numerator {}, new_denominator {};
-    
-    do
-    {
-        ++exponent;
-        new_denominator = times_power_of_2(is_overflow, 1, exponent);   
-        new_numerator = round_as_int(value * new_denominator);
-        
-        if (is_overflow || ((new_numerator < numerator) || (new_denominator < denominator)))
-        {
-            is_overflow = true;
-            std::cerr << "Overflow happened in PowerOfTwoApprox constructor for value " << value << " over "
-                << Nbits << " bits; everything is therefore set arbitrarily to zero at the moment." << std::endl;
-            numerator = exponent = 0;
-            break;
-        }
-    
-        numerator = new_numerator;
-        denominator = new_denominator;
-    }
-    while (numerator <= max_numerator);
-    
-    if (!is_overflow)
-    {    
-        --exponent;
-        denominator = times_power_of_2(is_overflow, 1, exponent); 
-        
-        if (is_overflow)
-            std::cerr << "Likely bug here: should have been seen in the do..while loop. An assert (would be "
-                "appropriate here!" << std::endl;
-        
-        numerator = round_as_int(value * denominator);
-    }
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    bool is_overflow { false };
-    int denominator = times_power_of_2(is_overflow, 1, exponent_); 
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in PowerOfTwoApprox denominator computation!" << std::endl;
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-    
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    bool is_overflow { false };
-    
-    // static_cast for the sake of `short` case: short + short -> int!
-    IntT ret = static_cast<IntT>(times_power_of_2(is_overflow, 
-                                                  approx.Numerator() * coefficient, 
-                                                  -approx.Exponent()));
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned." 
-            << std::endl;
-        return std::numeric_limits<IntT>::max(); // arbitrary value.
-    }    
-    
-    return ret;
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << approx.Numerator() << "/2^" << approx.Exponent();
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: ";
-    
-    if (is_overflow)
-        std::cerr << "Overflow!" << std::endl;
-    else
-        std::cout << after_bit_string << exact << " ~ " << approx << before_error << "  [error = " << error 
-            << "/" << resolution_ << "]"  << std::endl;    
-}
-
-
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-
-TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
-
-
-void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
-{
-    bool is_overflow { false };
-    PowerOfTwoApprox<int> approx(is_overflow, Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(is_overflow, Nbits, value, double_approx, "", oconv.str());
-}
-
-
-TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65);
-}
-
-
-void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
-{
-    Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    bool is_overflow { false };
-
-    PowerOfTwoApprox<IntT> approx1(is_overflow, Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(is_overflow, Nbits, value2);
-
-    IntT approx = coefficient1 * approx1 + coefficient2 * approx2;
-    
-    // Ugly trick to circumvent the fact we can't add a new argument to operator* to get the value of `overflow` 
-    // boolean. Fortunately we'll see a bit later how to deal properly with this.
-    if (approx == std::numeric_limits<IntT>::max())
-        is_overflow = true;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(is_overflow, Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    TestDisplayContainer container(3);
-    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
-    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
-    container.Register(new TestDisplaySum<short>(1000000));
-    
-    loop(4, 16, 4, container);
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice40.cpp b/TP/4-Templates/Solution/exercice40.cpp
deleted file mode 100644
index fe0b528deade8b3c52a4d5072d8227376fc7b666..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice40.cpp
+++ /dev/null
@@ -1,570 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-template<class IntT>
-IntT times_power_of_2(bool& is_overflow, IntT number, int exponent)
-{
-    constexpr auto half_max = std::numeric_limits<IntT>::max() / 2;
-    
-    while (exponent > 0)
-    { 
-        if (number < half_max)
-        {
-            number *= 2; 
-            exponent -= 1; 
-        }
-        else
-        {
-            is_overflow = true;
-            std::cerr << "Overflow in times_power_of_2 with number = " << number << " and exponent = " 
-                << exponent << std::endl;
-            return std::numeric_limits<IntT>::lowest(); // arbitrary value
-        }
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    return number;
-}
-
-//! Round to `x` the nearest integer.
-template<class IntT>
-IntT round_as_int(double x)
-{
-    return static_cast<IntT>(std::round(x));
-}
-
-//! Maximum integer that might be represented with `Nbits` bits.
-template<class IntT>
-IntT max_int(bool& is_overflow, int Nbits)
-{ 
-    return (times_power_of_2(is_overflow, static_cast<IntT>(1), Nbits) - 1);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(bool& is_overflow, int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(bool& is_overflow, int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    IntT denominator {};
-    
-    auto max_numerator = max_int<IntT>(is_overflow, Nbits);
-    
-    IntT new_numerator {}, new_denominator {};
-    
-    do
-    {
-        ++exponent;
-        new_denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent);   
-        new_numerator = round_as_int<IntT>(value * new_denominator);
-        
-        if (is_overflow || ((new_numerator < numerator) || (new_denominator < denominator)))
-        {
-            is_overflow = true;
-            std::cerr << "Overflow happened in PowerOfTwoApprox constructor for value " << value << " over "
-                << Nbits << " bits; everything is therefore set arbitrarily to zero at the moment." << std::endl;
-            numerator = exponent = 0;
-            break;
-        }
-    
-        numerator = new_numerator;
-        denominator = new_denominator;
-    }
-    while (numerator <= max_numerator);
-    
-    if (!is_overflow)
-    {    
-        --exponent;
-        denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent); 
-        
-        if (is_overflow)
-            std::cerr << "Likely bug here: should have been seen in the do..while loop. An assert (would be "
-                "appropriate here!" << std::endl;
-        
-        numerator = round_as_int<IntT>(value * denominator);
-    }
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    bool is_overflow { false };
-    int denominator = times_power_of_2(is_overflow, 1, exponent_); 
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in PowerOfTwoApprox denominator computation!" << std::endl;
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-    
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    bool is_overflow { false };
-    
-    // static_cast for the sake of `short` case: short + short -> int!
-    IntT ret = static_cast<IntT>(times_power_of_2<IntT>(is_overflow, 
-                                                        approx.Numerator() * coefficient, 
-                                                        -approx.Exponent()));
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned." 
-            << std::endl;
-        return std::numeric_limits<IntT>::max(); // arbitrary value.
-    }    
-    
-    return ret;
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << approx.Numerator() << "/2^" << approx.Exponent();
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int<int>(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: ";
-    
-    if (is_overflow)
-        std::cerr << "Overflow!" << std::endl;
-    else
-        std::cout << after_bit_string << exact << " ~ " << approx << before_error << "  [error = " << error 
-            << "/" << resolution_ << "]"  << std::endl;    
-}
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-
-TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
-
-
-void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
-{
-    bool is_overflow { false };
-    PowerOfTwoApprox<int> approx(is_overflow, Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(is_overflow, Nbits, value, double_approx, "", oconv.str());
-}
-
-
-TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65);
-}
-
-
-void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
-{
-    Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    bool is_overflow { false };
-
-    PowerOfTwoApprox<IntT> approx1(is_overflow, Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(is_overflow, Nbits, value2);
-
-    IntT approx = coefficient1 * approx1 + coefficient2 * approx2;
-    
-    // Ugly trick to circumvent the fact we can't add a new argument to operator* to get the value of `overflow` 
-    // boolean. Fortunately we'll see a bit later how to deal properly with this.
-    if (approx == std::numeric_limits<IntT>::max())
-        is_overflow = true;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(is_overflow, Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    TestDisplayContainer container(3);
-    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
-    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
-    container.Register(new TestDisplaySum<short>(1000000));
-    
-    loop(4, 16, 4, container);
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice41.cpp b/TP/4-Templates/Solution/exercice41.cpp
deleted file mode 100644
index 8967a892521b0aec6fcb3ee03af9081099d5618a..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice41.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-template<class IntT>
-IntT times_power_of_2(bool& is_overflow, IntT number, int exponent)
-{
-    constexpr auto half_max = std::numeric_limits<IntT>::max() / 2;
-    
-    while (exponent > 0)
-    { 
-        if (number < half_max)
-        {
-            number *= 2; 
-            exponent -= 1; 
-        }
-        else
-        {
-            is_overflow = true;
-            std::cerr << "Overflow in times_power_of_2 with number = " << number << " and exponent = " 
-                << exponent << std::endl;
-            return std::numeric_limits<IntT>::lowest(); // arbitrary value
-        }
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    return number;
-}
-
-//! Round to `x` the nearest integer.
-template<class IntT>
-IntT round_as_int(double x)
-{
-    return static_cast<IntT>(std::round(x));
-}
-
-//! Maximum integer that might be represented with `Nbits` bits.
-template<class IntT>
-IntT max_int(bool& is_overflow, int Nbits)
-{ 
-    return (times_power_of_2(is_overflow, static_cast<IntT>(1), Nbits) - 1);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(bool& is_overflow, int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(bool& is_overflow, int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    IntT denominator {};
-    
-    auto max_numerator = max_int<IntT>(is_overflow, Nbits);
-    
-    IntT new_numerator {}, new_denominator {};
-    
-    do
-    {
-        ++exponent;
-        new_denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent);   
-        new_numerator = round_as_int<IntT>(value * new_denominator);
-        
-        if (is_overflow || ((new_numerator < numerator) || (new_denominator < denominator)))
-        {
-            is_overflow = true;
-            std::cerr << "Overflow happened in PowerOfTwoApprox constructor for value " << value << " over "
-                << Nbits << " bits; everything is therefore set arbitrarily to zero at the moment." << std::endl;
-            numerator = exponent = 0;
-            break;
-        }
-    
-        numerator = new_numerator;
-        denominator = new_denominator;
-    }
-    while (numerator <= max_numerator);
-    
-    if (!is_overflow)
-    {    
-        --exponent;
-        denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent); 
-        
-        if (is_overflow)
-            std::cerr << "Likely bug here: should have been seen in the do..while loop. An assert (would be "
-                "appropriate here!" << std::endl;
-        
-        numerator = round_as_int<IntT>(value * denominator);
-    }
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    bool is_overflow { false };
-    int denominator = times_power_of_2(is_overflow, 1, exponent_); 
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in PowerOfTwoApprox denominator computation!" << std::endl;
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-    
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    bool is_overflow { false };
-    
-    IntT product {};
-    
-    if (__builtin_mul_overflow(approx.Numerator(), coefficient, &product))
-    {
-        is_overflow = true;
-        std::cerr << "Overflow in " << coefficient << " * " << approx.Numerator() << std::endl;
-    }
-    
-    // static_cast for the sake of `short` case: short + short -> int!
-    IntT ret = static_cast<IntT>(times_power_of_2<IntT>(is_overflow, 
-                                                        approx.Numerator() * coefficient, 
-                                                        -approx.Exponent()));
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned." 
-            << std::endl;
-        return std::numeric_limits<IntT>::max(); // arbitrary value.
-    }    
-    
-    return ret;
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << approx.Numerator() << "/2^" << approx.Exponent();
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int<int>(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: ";
-    
-    if (is_overflow)
-        std::cerr << "Overflow!" << std::endl;
-    else
-        std::cout << after_bit_string << exact << " ~ " << approx << before_error << "  [error = " << error 
-            << "/" << resolution_ << "]"  << std::endl;    
-}
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-
-TestDisplayPowerOfTwoApprox::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox::~TestDisplayPowerOfTwoApprox() = default;
-
-
-void TestDisplayPowerOfTwoApprox::Display(int Nbits, double value) const
-{
-    bool is_overflow { false };
-    PowerOfTwoApprox<int> approx(is_overflow, Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(is_overflow, Nbits, value, double_approx, "", oconv.str());
-}
-
-
-TestDisplayPowerOfTwoApprox065::TestDisplayPowerOfTwoApprox065(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-TestDisplayPowerOfTwoApprox035::TestDisplayPowerOfTwoApprox035(int resolution)
-: TestDisplayPowerOfTwoApprox(resolution)
-{ }
-
-
-void TestDisplayPowerOfTwoApprox065::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65);
-}
-
-
-void TestDisplayPowerOfTwoApprox035::operator()(int Nbits) const
-{
-    Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    bool is_overflow { false };
-
-    PowerOfTwoApprox<IntT> approx1(is_overflow, Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(is_overflow, Nbits, value2);
-
-    IntT first_term = coefficient1 * approx1;
-    IntT second_term = coefficient2 * approx2;
-    
-    IntT approx {};
-    
-    if (__builtin_add_overflow(first_term, second_term, &approx))
-    {
-        std::cerr << "Overflow in " << coefficient1 << " * " << approx1 << " + " 
-            << coefficient2 << " * " << approx2 << std::endl;
-        is_overflow = true;
-    }
-    
-    // Ugly trick to circumvent the fact we can't add a new argument to operator* to get the value of `overflow` 
-    // boolean. Fortunately we'll see a bit later how to deal properly with this.
-    if (approx == std::numeric_limits<IntT>::max())
-        is_overflow = true;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(is_overflow, Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    TestDisplayContainer container(3);
-    container.Register(new TestDisplayPowerOfTwoApprox065(1000000));
-    container.Register(new TestDisplayPowerOfTwoApprox035(1000000));
-    container.Register(new TestDisplaySum<short>(1000000));
-    
-    loop(4, 16, 4, container);
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice42.cpp b/TP/4-Templates/Solution/exercice42.cpp
deleted file mode 100644
index c542b42ddb61de084a4a3831f0af83d50fb5e35c..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice42.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-template<class IntT>
-IntT times_power_of_2(bool& is_overflow, IntT number, int exponent)
-{
-    constexpr auto half_max = std::numeric_limits<IntT>::max() / 2;
-    
-    while (exponent > 0)
-    { 
-        if (number < half_max)
-        {
-            number *= 2; 
-            exponent -= 1; 
-        }
-        else
-        {
-            is_overflow = true;
-            std::cerr << "Overflow in times_power_of_2 with number = " << number << " and exponent = " 
-                << exponent << std::endl;
-            return std::numeric_limits<IntT>::lowest(); // arbitrary value
-        }
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    return number;
-}
-
-//! Round to `x` the nearest integer.
-template<class IntT>
-IntT round_as_int(double x)
-{
-    return static_cast<IntT>(std::round(x));
-}
-
-//! Maximum integer that might be represented with `Nbits` bits.
-template<class IntT>
-IntT max_int(bool& is_overflow, int Nbits)
-{ 
-    return (times_power_of_2(is_overflow, static_cast<IntT>(1), Nbits) - 1);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(bool& is_overflow, int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(bool& is_overflow, int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    IntT denominator {};
-    
-    auto max_numerator = max_int<IntT>(is_overflow, Nbits);
-    
-    IntT new_numerator {}, new_denominator {};
-    
-    do
-    {
-        ++exponent;
-        new_denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent);   
-        new_numerator = round_as_int<IntT>(value * new_denominator);
-        
-        if (is_overflow || ((new_numerator < numerator) || (new_denominator < denominator)))
-        {
-            is_overflow = true;
-            std::cerr << "Overflow happened in PowerOfTwoApprox constructor for value " << value << " over "
-                << Nbits << " bits; everything is therefore set arbitrarily to zero at the moment." << std::endl;
-            numerator = exponent = 0;
-            break;
-        }
-    
-        numerator = new_numerator;
-        denominator = new_denominator;
-    }
-    while (numerator <= max_numerator);
-    
-    if (!is_overflow)
-    {    
-        --exponent;
-        denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent); 
-        
-        if (is_overflow)
-            std::cerr << "Likely bug here: should have been seen in the do..while loop. An assert (would be "
-                "appropriate here!" << std::endl;
-        
-        numerator = round_as_int<IntT>(value * denominator);
-    }
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    bool is_overflow { false };
-    int denominator = times_power_of_2(is_overflow, 1, exponent_); 
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in PowerOfTwoApprox denominator computation!" << std::endl;
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-    
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    bool is_overflow { false };
-    
-    IntT product {};
-    
-    if (__builtin_mul_overflow(approx.Numerator(), coefficient, &product))
-    {
-        is_overflow = true;
-        std::cerr << "Overflow in " << coefficient << " * " << approx.Numerator() << std::endl;
-    }
-    
-    // static_cast for the sake of `short` case: short + short -> int!
-    IntT ret = static_cast<IntT>(times_power_of_2<IntT>(is_overflow, 
-                                                        approx.Numerator() * coefficient, 
-                                                        -approx.Exponent()));
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned." 
-            << std::endl;
-        return std::numeric_limits<IntT>::max(); // arbitrary value.
-    }    
-    
-    return ret;
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << approx.Numerator() << "/2^" << approx.Exponent();
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int<int>(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: ";
-    
-    if (is_overflow)
-        std::cerr << "Overflow!" << std::endl;
-    else
-        std::cout << after_bit_string << exact << " ~ " << approx << before_error << "  [error = " << error 
-            << "/" << resolution_ << "]"  << std::endl;    
-}
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-template<class IntT>
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-template<class IntT>
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox<IntT>
-{
-public:
-    
-    //! Convenient alias.
-    using parent = TestDisplayPowerOfTwoApprox<IntT>;
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-template<class IntT>
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox<IntT>
-{
-public:
-    
-    //! Convenient alias.
-    using parent = TestDisplayPowerOfTwoApprox<IntT>;
-    
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox<IntT>::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox<IntT>::~TestDisplayPowerOfTwoApprox() = default;
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox<IntT>::Display(int Nbits, double value) const
-{
-    bool is_overflow { false };
-    PowerOfTwoApprox<int> approx(is_overflow, Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(is_overflow, Nbits, value, double_approx, "", oconv.str());
-}
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox065<IntT>::TestDisplayPowerOfTwoApprox065(int resolution)
-: parent(resolution)
-{ }
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox035<IntT>::TestDisplayPowerOfTwoApprox035(int resolution)
-: parent(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox065<IntT>::operator()(int Nbits) const
-{
-    parent::Display(Nbits, 0.65);
-}
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox035<IntT>::operator()(int Nbits) const
-{
-    parent::Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    bool is_overflow { false };
-
-    PowerOfTwoApprox<IntT> approx1(is_overflow, Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(is_overflow, Nbits, value2);
-
-    IntT first_term = coefficient1 * approx1;
-    IntT second_term = coefficient2 * approx2;
-    
-    IntT approx {};
-    
-    if (__builtin_add_overflow(first_term, second_term, &approx))
-    {
-        std::cerr << "Overflow in " << coefficient1 << " * " << approx1 << " + " 
-            << coefficient2 << " * " << approx2 << std::endl;
-        is_overflow = true;
-    }
-    
-    // Ugly trick to circumvent the fact we can't add a new argument to operator* to get the value of `overflow` 
-    // boolean. Fortunately we'll see a bit later how to deal properly with this.
-    if (approx == std::numeric_limits<IntT>::max())
-        is_overflow = true;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(is_overflow, Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    TestDisplayContainer container(3);
-    container.Register(new TestDisplayPowerOfTwoApprox065<int>(1000000));
-    container.Register(new TestDisplayPowerOfTwoApprox035<int>(1000000));
-    container.Register(new TestDisplaySum<int>(1000000));
-    
-    loop(4, 16, 4, container);
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice43.cpp b/TP/4-Templates/Solution/exercice43.cpp
deleted file mode 100644
index 31bb113e4d49c4eec5f4509255380fc4bd792860..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice43.cpp
+++ /dev/null
@@ -1,639 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-/*!
- * \brief Disambiguate char integers ONLY FOR STREAM OUTPUT.
- * 
- * This solution is one among others: we might as well have defined specialization of the class for char and
- * unsigned char, which would have been slightly more verbosy.
- */
-template<typename IntT>
-struct DisambiguateCharInt
-{
-    
-    using type = std::conditional_t<std::is_same<IntT, char>() || std::is_same<IntT, unsigned char>(),
-                                    int, IntT>;
-    
-    static type IntValue(IntT a)
-    {
-        return static_cast<type>(a);
-    }
-
-
-};
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-template<class IntT>
-IntT times_power_of_2(bool& is_overflow, IntT number, int exponent)
-{
-    constexpr auto half_max = std::numeric_limits<IntT>::max() / 2;
-    
-    while (exponent > 0)
-    { 
-        if (number < half_max)
-        {
-            number *= 2; 
-            exponent -= 1; 
-        }
-        else
-        {
-            is_overflow = true;
-            std::cerr << "Overflow in times_power_of_2 with number = " 
-                << DisambiguateCharInt<IntT>::IntValue(number) << " and exponent = " 
-                << exponent << std::endl;
-            return std::numeric_limits<IntT>::lowest(); // arbitrary value
-        }
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    return number;
-}
-
-//! Round to `x` the nearest integer.
-template<class IntT>
-IntT round_as_int(double x)
-{
-    return static_cast<IntT>(std::round(x));
-}
-
-//! Maximum integer that might be represented with `Nbits` bits.
-template<class IntT>
-IntT max_int(bool& is_overflow, int Nbits)
-{ 
-    return (times_power_of_2(is_overflow, static_cast<IntT>(1), Nbits) - 1);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(bool& is_overflow, int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(bool& is_overflow, int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    IntT denominator {};
-    
-    auto max_numerator = max_int<IntT>(is_overflow, Nbits);
-    
-    IntT new_numerator {}, new_denominator {};
-    
-    do
-    {
-        ++exponent;
-        new_denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent);   
-        new_numerator = round_as_int<IntT>(value * new_denominator);
-        
-        if (is_overflow || ((new_numerator < numerator) || (new_denominator < denominator)))
-        {
-            is_overflow = true;
-            std::cerr << "Overflow happened in PowerOfTwoApprox constructor for value " << value << " over "
-                << Nbits << " bits; everything is therefore set arbitrarily to zero at the moment." << std::endl;
-            numerator = exponent = 0;
-            break;
-        }
-    
-        numerator = new_numerator;
-        denominator = new_denominator;
-    }
-    while (numerator <= max_numerator);
-    
-    if (!is_overflow)
-    {    
-        --exponent;
-        denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent); 
-        
-        if (is_overflow)
-            std::cerr << "Likely bug here: should have been seen in the do..while loop. An assert (would be "
-                "appropriate here!" << std::endl;
-        
-        numerator = round_as_int<IntT>(value * denominator);
-    }
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    bool is_overflow { false };
-    int denominator = times_power_of_2(is_overflow, 1, exponent_); 
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in PowerOfTwoApprox denominator computation!" << std::endl;
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-    
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    bool is_overflow { false };
-    
-    IntT product {};
-    
-    if (__builtin_mul_overflow(approx.Numerator(), coefficient, &product))
-    {
-        is_overflow = true;
-        std::cerr << "Overflow in " << coefficient << " * " << approx.Numerator() << std::endl;
-    }
-    
-    // static_cast for the sake of `short` case: short + short -> int!
-    IntT ret = static_cast<IntT>(times_power_of_2<IntT>(is_overflow, 
-                                                        approx.Numerator() * coefficient, 
-                                                        -approx.Exponent()));
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned." 
-            << std::endl;
-        return std::numeric_limits<IntT>::max(); // arbitrary value.
-    }    
-    
-    return ret;
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << DisambiguateCharInt<IntT>::IntValue(approx.Numerator()) << "/2^" << approx.Exponent();
-        
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int<int>(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: ";
-    
-    if (is_overflow)
-        std::cerr << "Overflow!" << std::endl;
-    else
-        std::cout << after_bit_string << exact << " ~ " << approx << before_error << "  [error = " << error 
-            << "/" << resolution_ << "]"  << std::endl;    
-}
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-template<class IntT>
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.    
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-template<class IntT>
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox<IntT>
-{
-public:
-    
-    //! Convenient alias.
-    using parent = TestDisplayPowerOfTwoApprox<IntT>;
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-template<class IntT>
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox<IntT>
-{
-public:
-    
-    //! Convenient alias.
-    using parent = TestDisplayPowerOfTwoApprox<IntT>;
-    
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox<IntT>::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox<IntT>::~TestDisplayPowerOfTwoApprox() = default;
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox<IntT>::Display(int Nbits, double value) const
-{
-    bool is_overflow { false };
-    PowerOfTwoApprox<IntT> approx(is_overflow, Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(is_overflow, Nbits, value, double_approx, "", oconv.str());
-}
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox065<IntT>::TestDisplayPowerOfTwoApprox065(int resolution)
-: parent(resolution)
-{ }
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox035<IntT>::TestDisplayPowerOfTwoApprox035(int resolution)
-: parent(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox065<IntT>::operator()(int Nbits) const
-{
-    parent::Display(Nbits, 0.65);
-}
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox035<IntT>::operator()(int Nbits) const
-{
-    parent::Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    bool is_overflow { false };
-
-    PowerOfTwoApprox<IntT> approx1(is_overflow, Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(is_overflow, Nbits, value2);
-
-    IntT first_term = coefficient1 * approx1;
-    IntT second_term = coefficient2 * approx2;
-    
-    IntT approx {};
-    
-    if (__builtin_add_overflow(first_term, second_term, &approx))
-    {
-        std::cerr << "Overflow in " << coefficient1 << " * " << approx1 << " + " 
-            << coefficient2 << " * " << approx2 << std::endl;
-        is_overflow = true;
-    }
-    
-    // Ugly trick to circumvent the fact we can't add a new argument to operator* to get the value of `overflow` 
-    // boolean. Fortunately we'll see a bit later how to deal properly with this.
-    if (approx == std::numeric_limits<IntT>::max())
-        is_overflow = true;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(is_overflow, Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-class TestDisplayContainer
-{
-public:
-    
-    //! Constructor.
-    TestDisplayContainer(std::size_t size);
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Size of the array.
-    const std::size_t size_ = 0;
-
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-TestDisplayContainer::TestDisplayContainer(std::size_t size)
-: size_(size)
-{
-    test_display_list_ = new TestDisplay*[size];
-
-    for (auto i = 0ul; i < size; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-TestDisplayContainer::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-void TestDisplayContainer::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= static_cast<int>(size_))
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-int TestDisplayContainer::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-TestDisplay& TestDisplayContainer::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    {
-        TestDisplayContainer container(3);
-        container.Register(new TestDisplayPowerOfTwoApprox065<int>(1000000));
-        container.Register(new TestDisplayPowerOfTwoApprox035<int>(1000000));
-        container.Register(new TestDisplaySum<int>(1000000));
-    
-        loop(4, 16, 4, container);
-    }
-    
-    {
-        TestDisplayContainer container(2);
-        container.Register(new TestDisplayPowerOfTwoApprox065<char>(1000));
-        container.Register(new TestDisplayPowerOfTwoApprox065<unsigned char>(1000));
-        loop(1, 8, 1, container);        
-        
-        
-    }
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/Solution/exercice44.cpp b/TP/4-Templates/Solution/exercice44.cpp
deleted file mode 100644
index 9605b985235adf18e792d5184367234b2d768e76..0000000000000000000000000000000000000000
--- a/TP/4-Templates/Solution/exercice44.cpp
+++ /dev/null
@@ -1,644 +0,0 @@
-#include <iostream>
-#include <cmath> // for std::round
-#include <string>
-#include <sstream> // for std::ostringstream
-
-
-/*!
- * \brief Disambiguate char integers ONLY FOR STREAM OUTPUT.
- * 
- * This solution is one among others: we might as well have defined specialization of the class for char and
- * unsigned char, which would have been slightly more verbosy.
- */
-template<typename IntT>
-struct DisambiguateCharInt
-{
-    
-    using type = std::conditional_t<std::is_same<IntT, char>() || std::is_same<IntT, unsigned char>(),
-                                    int, IntT>;
-    
-    static type IntValue(IntT a)
-    {
-        return static_cast<type>(a);
-    }
-
-
-};
-
-
-
-//! Returns `number` * (2 ^ `exponent`) 
-template<class IntT>
-IntT times_power_of_2(bool& is_overflow, IntT number, int exponent)
-{
-    constexpr auto half_max = std::numeric_limits<IntT>::max() / 2;
-    
-    while (exponent > 0)
-    { 
-        if (number < half_max)
-        {
-            number *= 2; 
-            exponent -= 1; 
-        }
-        else
-        {
-            is_overflow = true;
-            std::cerr << "Overflow in times_power_of_2 with number = " 
-                << DisambiguateCharInt<IntT>::IntValue(number) << " and exponent = " 
-                << exponent << std::endl;
-            return std::numeric_limits<IntT>::lowest(); // arbitrary value
-        }
-    }
-    while (exponent < 0)
-    { 
-        number /= 2;
-        exponent += 1 ; 
-    }
-    
-    return number;
-}
-
-//! Round to `x` the nearest integer.
-template<class IntT>
-IntT round_as_int(double x)
-{
-    return static_cast<IntT>(std::round(x));
-}
-
-//! Maximum integer that might be represented with `Nbits` bits.
-template<class IntT>
-IntT max_int(bool& is_overflow, int Nbits)
-{ 
-    return (times_power_of_2(is_overflow, static_cast<IntT>(1), Nbits) - 1);
-}
-
-//! Function to call when an error occurred; its aborts the program.
-[[noreturn]] void error(std::string explanation)
-{
-    std::cout << "ERROR: " << explanation << std::endl;
-    exit(EXIT_FAILURE);
-}
-
-/************************************/
-// PowerOfTwoApprox 
-/************************************/
-
-/*!
- * \brief  Structure to group together numerator and exponent used to represent a floating-point.
- * 
- * Representation is numerator / 2^exponent, where numerator is as large as a selected number of bits make possible.
- */
-template<class IntT>
-class PowerOfTwoApprox
-{
-public:
-    //! Constructor that compute the best possible approximation of `value` with `Nbits`
-    PowerOfTwoApprox(bool& is_overflow, int Nbits, double value);
-    
-    //! Returns the double value computed from `numerator_` and `exponent_`.
-    explicit operator double() const;
-    
-   /*! 
-    * \brief Multiply the approximate representation by an integer. 
-    * 
-    * \param[in] coefficient Integer coefficient by which the object is multiplied.
-    * 
-    * \return An approximate integer result of the multiplication.
-    */
-    template<class IntU>
-    friend IntU operator*(const PowerOfTwoApprox<IntU>& approx, IntU coefficient);
-
-    template<class IntU>    
-    friend IntU operator*(IntU coefficient, const PowerOfTwoApprox<IntU>& approx);
-    
-    //! Get the value of the numerator.
-    IntT Numerator() const;
-    
-    //! Get the value of the exponent.
-    int Exponent() const;
-        
-private:
-    
-    //! Numerator.
-    IntT numerator_ = 0;
-    
-    //! Exponent applied to the 2 at the denominator.
-    int exponent_ = 0;    
-};
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::PowerOfTwoApprox(bool& is_overflow, int Nbits, double value)
-{
-    auto& numerator = numerator_;
-    auto& exponent = exponent_;
-    
-    numerator = exponent = 0;
-    IntT denominator {};
-    
-    auto max_numerator = max_int<IntT>(is_overflow, Nbits);
-    
-    IntT new_numerator {}, new_denominator {};
-    
-    do
-    {
-        ++exponent;
-        new_denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent);   
-        new_numerator = round_as_int<IntT>(value * new_denominator);
-        
-        if (is_overflow || ((new_numerator < numerator) || (new_denominator < denominator)))
-        {
-            is_overflow = true;
-            std::cerr << "Overflow happened in PowerOfTwoApprox constructor for value " << value << " over "
-                << Nbits << " bits; everything is therefore set arbitrarily to zero at the moment." << std::endl;
-            numerator = exponent = 0;
-            break;
-        }
-    
-        numerator = new_numerator;
-        denominator = new_denominator;
-    }
-    while (numerator <= max_numerator);
-    
-    if (!is_overflow)
-    {    
-        --exponent;
-        denominator = times_power_of_2(is_overflow, static_cast<IntT>(1), exponent); 
-        
-        if (is_overflow)
-            std::cerr << "Likely bug here: should have been seen in the do..while loop. An assert (would be "
-                "appropriate here!" << std::endl;
-        
-        numerator = round_as_int<IntT>(value * denominator);
-    }
-}
-
-
-template<class IntT>
-PowerOfTwoApprox<IntT>::operator double() const
-{
-    bool is_overflow { false };
-    int denominator = times_power_of_2(is_overflow, 1, exponent_); 
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in PowerOfTwoApprox denominator computation!" << std::endl;
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-    
-    return static_cast<double>(numerator_) / denominator;
-}
-
-
-template<class IntT>
-IntT PowerOfTwoApprox<IntT>::Numerator() const
-{
-    return numerator_;
-}
-
-
-template<class IntT>
-int PowerOfTwoApprox<IntT>::Exponent() const
-{
-    return exponent_;
-}
-
-
-template<class IntT>
-IntT operator*(const PowerOfTwoApprox<IntT>& approx, IntT coefficient)
-{
-    bool is_overflow { false };
-    
-    IntT product {};
-    
-    if (__builtin_mul_overflow(approx.Numerator(), coefficient, &product))
-    {
-        is_overflow = true;
-        std::cerr << "Overflow in " << coefficient << " * " << approx.Numerator() << std::endl;
-    }
-    
-    // static_cast for the sake of `short` case: short + short -> int!
-    IntT ret = static_cast<IntT>(times_power_of_2<IntT>(is_overflow, 
-                                                        approx.Numerator() * coefficient, 
-                                                        -approx.Exponent()));
-    
-    if (is_overflow)
-    {
-        std::cerr << "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary value MAX_INT will therefore be returned." 
-            << std::endl;
-        return std::numeric_limits<IntT>::max(); // arbitrary value.
-    }    
-    
-    return ret;
-}
-
-
-template<class IntT>
-IntT operator*(IntT coefficient, const PowerOfTwoApprox<IntT>& approx)
-{
-    return approx * coefficient;
-}
-
-
-namespace std
-{
-    
-    
-    template<class IntT>
-    std::ostream& operator<<(std::ostream& out, const PowerOfTwoApprox<IntT>& approx)
-    {
-        out << DisambiguateCharInt<IntT>::IntValue(approx.Numerator()) << "/2^" << approx.Exponent();
-        
-        return out;
-    }
-
-
-} // namespace std
-    
-    
-
-/************************************/
-// TestDisplay 
-/************************************/
-
-/*!
- * \brief Base class for TestDisplayPowerOfTwoApprox and TestDisplaySum.
- */
-class TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplay(int resolution);
-    
-    //! Virtual method.
-    virtual void operator()(int Nbits) const = 0;
-    
-    //! Virtual destructor.
-    virtual ~TestDisplay();
-    
-protected:
-    
-   /*!
-    * \brief  Print a line with information about error.
-    *
-    * \param[in] after_bit_string String that might appear
-    */
-   void PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                            std::string after_bit_string, std::string before_error) const;
-                              
-    
-private:
-    
-    //! Maximum error index.
-    const int resolution_;
-
-};
-
-
-
-TestDisplay::TestDisplay(int resolution)
-: resolution_(resolution)
-{ }
-
-
-TestDisplay::~TestDisplay() = default;
-
-
-void TestDisplay::PrintNumericalError(bool is_overflow, int Nbits, double exact, double approx,
-                                      std::string after_bit_string, std::string before_error) const
-{
-    int error = round_as_int<int>(resolution_ * std::fabs(exact - approx) / exact);
-    
-    std::cout << "[With " << Nbits << " bits]: ";
-    
-    if (is_overflow)
-        std::cerr << "Overflow!" << std::endl;
-    else
-        std::cout << after_bit_string << exact << " ~ " << approx << before_error << "  [error = " << error 
-            << "/" << resolution_ << "]"  << std::endl;    
-}
-
-
-
-/*!
- * \brief Class in charge of displaying the approximation for PowerOfTwoApprox for a value which is expected
- * to be provided in a derived class.
- */
-template<class IntT>
-class TestDisplayPowerOfTwoApprox : public TestDisplay
-{
-public:
-    
-    //! Constructor.    
-    TestDisplayPowerOfTwoApprox(int resolution);
-    
-    //! Virtual destructor.
-    virtual ~TestDisplayPowerOfTwoApprox();
-    
-protected:
-    
-    //! Print the output for `value` when `Nbits` are available.
-    void Display(int Nbits, double value) const;
-
-};
-
-
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.65
-template<class IntT>
-class TestDisplayPowerOfTwoApprox065 : public TestDisplayPowerOfTwoApprox<IntT>
-{
-public:
-    
-    //! Convenient alias.
-    using parent = TestDisplayPowerOfTwoApprox<IntT>;
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox065(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-//! Run TestDisplayPowerOfTwoApprox for value 0.35
-template<class IntT>
-class TestDisplayPowerOfTwoApprox035 : public TestDisplayPowerOfTwoApprox<IntT>
-{
-public:
-    
-    //! Convenient alias.
-    using parent = TestDisplayPowerOfTwoApprox<IntT>;
-    
-    
-    //! Constructor.
-    TestDisplayPowerOfTwoApprox035(int resolution);
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-
-};
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox<IntT>::TestDisplayPowerOfTwoApprox(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox<IntT>::~TestDisplayPowerOfTwoApprox() = default;
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox<IntT>::Display(int Nbits, double value) const
-{
-    bool is_overflow { false };
-    PowerOfTwoApprox<IntT> approx(is_overflow, Nbits, value);
-    
-    double double_approx = static_cast<double>(approx);
-    
-    std::ostringstream oconv;
-    oconv << "  (" << approx << ')';
-    
-    PrintNumericalError(is_overflow, Nbits, value, double_approx, "", oconv.str());
-}
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox065<IntT>::TestDisplayPowerOfTwoApprox065(int resolution)
-: parent(resolution)
-{ }
-
-
-template<class IntT>
-TestDisplayPowerOfTwoApprox035<IntT>::TestDisplayPowerOfTwoApprox035(int resolution)
-: parent(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox065<IntT>::operator()(int Nbits) const
-{
-    parent::Display(Nbits, 0.65);
-}
-
-
-template<class IntT>
-void TestDisplayPowerOfTwoApprox035<IntT>::operator()(int Nbits) const
-{
-    parent::Display(Nbits, 0.35);
-}
-
-    
-    
-
-/*!
- * \brief Class in charge of displaying the approximation for 0.65 * 3515 + 0.35 * 4832.
-
- */
-template<class IntT>
-class TestDisplaySum : public TestDisplay
-{
-public:
-    
-    //! Constructor.
-    TestDisplaySum(int resolution);
-    
-    
-    //! Print the output for the values 0.65 and 0.35.
-    void operator()(int Nbits) const override;
-    
-private:
-    
-    //! Print the output for the approximation of the sum value1 * coefficient1 + value2 * coefficient2.
-    void Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const;
-
-};
-
-
-template<class IntT>
-TestDisplaySum<IntT>::TestDisplaySum(int resolution)
-: TestDisplay(resolution)
-{ }
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::operator()(int Nbits) const
-{
-    Display(Nbits, 0.65, 3515, 0.35, 4832);
-}
-
-
-template<class IntT>
-void TestDisplaySum<IntT>::Display(int Nbits, double value1, IntT coefficient1, double value2, IntT coefficient2) const
-{
-    double exact = std::round(value1 * coefficient1 + value2 * coefficient2);
-
-    bool is_overflow { false };
-
-    PowerOfTwoApprox<IntT> approx1(is_overflow, Nbits, value1);
-    PowerOfTwoApprox<IntT> approx2(is_overflow, Nbits, value2);
-
-    IntT first_term = coefficient1 * approx1;
-    IntT second_term = coefficient2 * approx2;
-    
-    IntT approx {};
-    
-    if (__builtin_add_overflow(first_term, second_term, &approx))
-    {
-        std::cerr << "Overflow in " << coefficient1 << " * " << approx1 << " + " 
-            << coefficient2 << " * " << approx2 << std::endl;
-        is_overflow = true;
-    }
-    
-    // Ugly trick to circumvent the fact we can't add a new argument to operator* to get the value of `overflow` 
-    // boolean. Fortunately we'll see a bit later how to deal properly with this.
-    if (approx == std::numeric_limits<IntT>::max())
-        is_overflow = true;
-        
-    std::ostringstream oconv;
-    oconv << value1 << " * " << coefficient1  << " + " << value2 << " * " << coefficient2 << " = ";
-    
-    PrintNumericalError(is_overflow, Nbits, exact, static_cast<double>(approx), oconv.str(), "");
-}
-
-
-
-//! Class which stores several `TestDisplay` as pointers.
-template<int SizeT>
-class TestDisplayContainer
-{
-public:
-    
-    static_assert(SizeT > 0);
-    
-    //! Constructor.
-    TestDisplayContainer();
-    
-    //! Destructor.
-    ~TestDisplayContainer();
-        
-    //! Insert a new `TestDisplay` object at the `next_position_available_`.
-    void Register(TestDisplay* test_display);
-    
-    //! Returns the number of registered elements.
-    int Nelement() const;
-    
-    //! Provide access to the `i`-th element.
-    TestDisplay& operator[](int i) const;
-
-private:
-    
-    //! Store `TestDisplay` objects upon which the display will be called.
-    TestDisplay** test_display_list_;
-    
-    //! Position in which the next `TestDisplay` will be put.
-    int next_position_available_ = 0;
-};
-
-
-
-template<int SizeT>
-TestDisplayContainer<SizeT>::TestDisplayContainer()
-{
-    test_display_list_ = new TestDisplay*[SizeT];
-
-    for (auto i = 0; i < SizeT; ++i)
-        test_display_list_[i] = nullptr;
-}
-
-
-template<int SizeT>
-TestDisplayContainer<SizeT>::~TestDisplayContainer()
-{
-    for (int position = 0; position < next_position_available_; ++position)
-        delete test_display_list_[position];
-    
-    delete[] test_display_list_;
-}
-
-
-template<int SizeT>
-void TestDisplayContainer<SizeT>::Register(TestDisplay* test_display)
-{
-    if (next_position_available_ >= SizeT)
-        error("Too many `TestDisplay` registered!");
-    
-    test_display_list_[next_position_available_++] = test_display;
-}
-
-
-template<int SizeT>
-int TestDisplayContainer<SizeT>::Nelement() const
-{
-    return next_position_available_;
-}
-
-
-template<int SizeT>
-TestDisplay& TestDisplayContainer<SizeT>::operator[](int i) const
-{
-    if (i < 0 || i >= next_position_available_)
-        error("Invalid index in TestDisplayContainer::operator[] request!");
-    
-    decltype(auto) element_ptr = test_display_list_[i];
-    return *element_ptr;
-}
-    
-
-
-//! Loop over the content of `TestDisplayContainer`.
-template<int SizeT>
-void loop(int Nbits_min, int Nbits_max, int Nbits_increment, TestDisplayContainer<SizeT>& container)
-{
-    int Nelement = container.Nelement();
-    
-    for (int position = 0; position < Nelement; ++position)
-    {
-        decltype(auto) test_display = container[position];
-        
-        for (int Nbits = Nbits_min; Nbits <= Nbits_max; Nbits += Nbits_increment)
-             test_display(Nbits); 
-    
-        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 
-        
-    {
-        TestDisplayContainer<3> container;
-        container.Register(new TestDisplayPowerOfTwoApprox065<int>(1000000));
-        container.Register(new TestDisplayPowerOfTwoApprox035<int>(1000000));
-        container.Register(new TestDisplaySum<int>(1000000));
-    
-        loop(4, 16, 4, container);
-    }
-    
-    {
-        TestDisplayContainer<2> container;
-        container.Register(new TestDisplayPowerOfTwoApprox065<char>(1000));
-        container.Register(new TestDisplayPowerOfTwoApprox065<unsigned char>(1000));
-        loop(1, 8, 1, container);        
-        
-        
-    }
-
-    return EXIT_SUCCESS;
-}
-
diff --git a/TP/4-Templates/initial_file.cpp b/TP/4-Templates/initial_file.cpp
index d08d48c228af5557a63b1082cc064f1d57e06680..ae1b7da1c0d74fe461ced4abe6b9a340f8532a83 120000
--- a/TP/4-Templates/initial_file.cpp
+++ b/TP/4-Templates/initial_file.cpp
@@ -1 +1 @@
-../3-Operators/Solution/exercice36.cpp
\ No newline at end of file
+../3-Operators/Solution/exercice30.cpp
\ No newline at end of file