Commit 9da5bd90 by GILLES Sebastien

### Provide new solutions to template exercices.

parent ececfacb
 ... ... @@ -32,9 +32,9 @@ "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", "The integer type used for the `numerator_ `attribute of the `PowerOfTwoApprox` class was chosen arbitrarily. Make it a class template parameter.\n", "\n", "Only the numerator will be modified: the denominator and the number of bits remain `int`.\n", "Only this attribute will be modified: the denominator and the number of bits remain `int`.\n", "\n", "Make sure to modify:\n", "\n", ... ... @@ -81,14 +81,14 @@ "\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", "We will do so step by step, each exercice dealing with part of the changes (this is \n", "\n", "In the first step, we will:\n", "\n", "* Modify `operator*` signature so that the return type and the argument use the template parameter rather than `int`.\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", "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", "**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." ] ... ... @@ -105,10 +105,10 @@ "\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", "- `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", ... ... @@ -140,6 +140,7 @@ "[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", ... ... @@ -170,28 +171,9 @@ }, { "cell_type": "code", "execution_count": 1, "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[1minput_line_7:2:22: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno template named 'PowerOfTwoApprox'\u001b[0m\n", "IntT operator*(const PowerOfTwoApprox& approx, IntT coefficient)\n", "\u001b[0;1;32m ^\n", "\u001b[0m" ] }, { "ename": "Interpreter Error", "evalue": "", "output_type": "error", "traceback": [ "Interpreter Error: " ] } ], "outputs": [], "source": [ "// Doesn't run in Xeus-cling\n", "\n", ... ... @@ -203,6 +185,34 @@ "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you're doing such a cast though, you should end up with 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", "[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": {}, ... ... @@ -220,15 +230,15 @@ "The functions to use are:\n", "\n", "````\n", "__builtin_add_overflow(T a, T b, T& sum)\n", "__builtin_mul_overflow(T a, T b, T& product)\n", "__builtin_add_overflow(T a, T b, T* sum)\n", "__builtin_mul_overflow(T a, T b, T* product)\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::Display()` and `operator*(const PowerOfTwoApprox& approx, IntT coefficient)` to control the arithmetic operations there.\n", "\n", "Expected result is:\n", "Expected result is something like:\n", "\n", "````\n", "[With 4 bits]: 0.65 ~ 0.625 (10/2^4) [error = 38462/1000000]\n", ... ... @@ -241,21 +251,27 @@ "[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 operator*(PowerOfTwoApprox, integer)! Arbitrary max value will therefore be returned.\n", "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary max value will therefore be returned.\n", "Overflow in estDisplaySum::Display in sum.\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 operator*(PowerOfTwoApprox, integer)! Arbitrary max value will therefore be returned.\n", "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary max value will therefore be returned.\n", "Overflow in estDisplaySum::Display in sum.\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 operator*(PowerOfTwoApprox, integer)! Arbitrary max value will therefore be returned.\n", "Overflow in operator*(PowerOfTwoApprox, integer)! Arbitrary max value will therefore be returned.\n", "Overflow in estDisplaySum::Display in sum.\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!\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!\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" ... ...
 %% Cell type:markdown id: tags: # [Getting started in C++](/) - [Templates](/notebooks/4-Templates/0-main.ipynb) - [TP 11](/notebooks/4-Templates/1b-TP.ipynb) %% Cell type:markdown id: tags: