"At the moment, we will renege the sound principle of separating the functionalities (humour me for the moment...) and this function will:\n",
"At the moment, we will renege the sound principle of separating the functionalities (humour me for the moment...) and this function will:\n",
"\n",
"\n",
"* Take as arguments the number of bits, the exact actual number (obtained through usual floating-point arithmetic) and the approximation of this number through our representation.\n",
"* Take as arguments the number of bits, the exact actual number (obtained through usual floating-point arithmetic) and the approximation of this number through our representation.\n",
"* Compute the error with a resolution also given as argument ((i.e. the maximum index against which error is expressed - 100 and 1000 respectively up to now).\n",
"* Compute the error with a resolution also given as argument (i.e. the maximum index against which error is expressed - 100 and 1000 respectively up to now).\n",
"\n",
"\n",
"However there are subtleties in the way the lines are displayed: the parts in red is supplementary text that\n",
"However there are subtleties in the way the lines are displayed: the parts in red is supplementary text that\n",
"\n",
"\n",
...
@@ -206,14 +206,14 @@
...
@@ -206,14 +206,14 @@
"kernelspec": {
"kernelspec": {
"display_name": "C++17",
"display_name": "C++17",
"language": "C++17",
"language": "C++17",
"name": "xeus-cling-cpp17"
"name": "xcpp17"
},
},
"language_info": {
"language_info": {
"codemirror_mode": "text/x-c++src",
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"mimetype": "text/x-c++src",
"name": "c++",
"name": "c++",
"version": "-std=c++17"
"version": "17"
},
},
"latex_envs": {
"latex_envs": {
"LaTeX_envs_menu_present": true,
"LaTeX_envs_menu_present": true,
...
...
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# [Getting started in C++](/) - [Object programming](/notebooks/2-ObjectProgramming/0-main.ipynb) - [TP 7](/notebooks/2-ObjectProgramming/4b-TP.ipynb)
# [Getting started in C++](/) - [Object programming](/notebooks/2-ObjectProgramming/0-main.ipynb) - [TP 7](/notebooks/2-ObjectProgramming/4b-TP.ipynb)
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#EXERCICE-16:-transform-struct-PowerOfTwoApprox-into-a-class"data-toc-modified-id="EXERCICE-16:-transform-struct-PowerOfTwoApprox-into-a-class-1">EXERCICE 16: transform struct <code>PowerOfTwoApprox</code> into a class</a></span></li><li><span><ahref="#EXERCICE-17:-transform-multiply()-into-a-method-Multiply()-of-PowerOfTwoApprox"data-toc-modified-id="EXERCICE-17:-transform-multiply()-into-a-method-Multiply()-of-PowerOfTwoApprox-2">EXERCICE 17: transform <code>multiply()</code> into a method <code>Multiply()</code> of <code>PowerOfTwoApprox</code></a></span></li><li><span><ahref="#EXERCICE-18:-transform-display_power_of_2_approx()-into-a-class"data-toc-modified-id="EXERCICE-18:-transform-display_power_of_2_approx()-into-a-class-3">EXERCICE 18: transform <code>display_power_of_2_approx()</code> into a class</a></span></li><li><span><ahref="#EXERCICE-19:-transform-display_multiply()-into-a-class"data-toc-modified-id="EXERCICE-19:-transform-display_multiply()-into-a-class-4">EXERCICE 19: transform <code>display_multiply()</code> into a class</a></span></li><li><span><ahref="#EXERCICE-20:-introduce-common-print_line()-function-for-outputs"data-toc-modified-id="EXERCICE-20:-introduce-common-print_line()-function-for-outputs-5">EXERCICE 20: introduce common <code>print_line()</code> function for outputs</a></span></li></ul></div>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#EXERCICE-16:-transform-struct-PowerOfTwoApprox-into-a-class"data-toc-modified-id="EXERCICE-16:-transform-struct-PowerOfTwoApprox-into-a-class-1">EXERCICE 16: transform struct <code>PowerOfTwoApprox</code> into a class</a></span></li><li><span><ahref="#EXERCICE-17:-transform-multiply()-into-a-method-Multiply()-of-PowerOfTwoApprox"data-toc-modified-id="EXERCICE-17:-transform-multiply()-into-a-method-Multiply()-of-PowerOfTwoApprox-2">EXERCICE 17: transform <code>multiply()</code> into a method <code>Multiply()</code> of <code>PowerOfTwoApprox</code></a></span></li><li><span><ahref="#EXERCICE-18:-transform-display_power_of_2_approx()-into-a-class"data-toc-modified-id="EXERCICE-18:-transform-display_power_of_2_approx()-into-a-class-3">EXERCICE 18: transform <code>display_power_of_2_approx()</code> into a class</a></span></li><li><span><ahref="#EXERCICE-19:-transform-display_multiply()-into-a-class"data-toc-modified-id="EXERCICE-19:-transform-display_multiply()-into-a-class-4">EXERCICE 19: transform <code>display_multiply()</code> into a class</a></span></li><li><span><ahref="#EXERCICE-20:-introduce-common-print_line()-function-for-outputs"data-toc-modified-id="EXERCICE-20:-introduce-common-print_line()-function-for-outputs-5">EXERCICE 20: introduce common <code>print_line()</code> function for outputs</a></span></li></ul></div>
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 16: transform struct `PowerOfTwoApprox` into a class
### EXERCICE 16: transform struct `PowerOfTwoApprox` into a class
Make `PowerOfTwoApprox` into a class, with proper encapsulation:
Make `PowerOfTwoApprox` into a class, with proper encapsulation:
* Both data attributes should be made private.
* Both data attributes should be made private.
* Constant accessors will therefore be needed (non-constant ones should not be required here)
* Constant accessors will therefore be needed (non-constant ones should not be required here)
Expected output is the same as previously.
Expected output is the same as previously.
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 17: transform `multiply()` into a method `Multiply()` of `PowerOfTwoApprox`
### EXERCICE 17: transform `multiply()` into a method `Multiply()` of `PowerOfTwoApprox`
The method will take as argument only the integer coefficient.
The method will take as argument only the integer coefficient.
`display_multiply()` will of course need also some light rewriting to accomodate that change.
`display_multiply()` will of course need also some light rewriting to accomodate that change.
Expected output is the same as previously.
Expected output is the same as previously.
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 18: transform `display_power_of_2_approx()` into a class
### EXERCICE 18: transform `display_power_of_2_approx()` into a class
Create a class `TestDisplayPowerOfTwoApprox` which will be in charge of printing the display for the 0.65 and 0.35 values.
Create a class `TestDisplayPowerOfTwoApprox` which will be in charge of printing the display for the 0.65 and 0.35 values.
Use two methods in this class:
Use two methods in this class:
* A public method `Do()` which will call the test for 0.65 and 0.35; this method will take the number of bits as argument.
* A public method `Do()` which will call the test for 0.65 and 0.35; this method will take the number of bits as argument.
* A private method `Display()` which will provide the display for a given double value (and will therefore be called twice: once for 0.65 and once for 0.35).
* A private method `Display()` which will provide the display for a given double value (and will therefore be called twice: once for 0.65 and once for 0.35).
New main should look like:
New main should look like:
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` C++17
``` C++17
int main(int argc, char** argv)
int main(int argc, char** argv)
{
{
static_cast<void>(argc); // to silence warning about unused argc - don't bother
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
static_cast<void>(argv); // to silence warning about unused argv - don't bother
### EXERCICE 19: transform `display_multiply()` into a class
### EXERCICE 19: transform `display_multiply()` into a class
Likewise, create a class `TestDisplayMultiply` which will be in charge of printing the display for 0.65 * 3515 + 0.35 * 4832 with public method `Do()` and private method `Display()` which will takes 5 arguments:
Likewise, create a class `TestDisplayMultiply` which will be in charge of printing the display for 0.65 * 3515 + 0.35 * 4832 with public method `Do()` and private method `Display()` which will takes 5 arguments:
* Number of bits.
* Number of bits.
* The two floating point values.
* The two floating point values.
* Their integer coefficient.
* Their integer coefficient.
New `main()` is:
New `main()` is:
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` C++17
``` C++17
int main(int argc, char** argv)
int main(int argc, char** argv)
{
{
static_cast<void>(argc); // to silence warning about unused argc - don't bother
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
static_cast<void>(argv); // to silence warning about unused argv - don't bother
TestDisplayPowerOfTwoApprox test_display_approx;
TestDisplayPowerOfTwoApprox test_display_approx;
for (int Nbits = 2; Nbits <= 8; Nbits += 2)
for (int Nbits = 2; Nbits <= 8; Nbits += 2)
test_display_approx.Do(Nbits);
test_display_approx.Do(Nbits);
std::cout << std::endl;
std::cout << std::endl;
TestDisplayMultiply test_display_multiply;
TestDisplayMultiply test_display_multiply;
for (int Nbits = 1; Nbits <= 8; ++Nbits)
for (int Nbits = 1; Nbits <= 8; ++Nbits)
test_display_multiply.Do(Nbits);
test_display_multiply.Do(Nbits);
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}
}
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 20: introduce common `print_line()` function for outputs
### EXERCICE 20: introduce common `print_line()` function for outputs
Both `TestDisplay` classes are rather similar in the line in charge of printing content on standard output - so we would like to uniformize the implementation.
Both `TestDisplay` classes are rather similar in the line in charge of printing content on standard output - so we would like to uniformize the implementation.
We will therefore introduce a `print_line()` function which will be in charge of printing the line for a given number of bits.
We will therefore introduce a `print_line()` function which will be in charge of printing the line for a given number of bits.
At the moment, we will renege the sound principle of separating the functionalities (humour me for the moment...) and this function will:
At the moment, we will renege the sound principle of separating the functionalities (humour me for the moment...) and this function will:
* Take as arguments the number of bits, the exact actual number (obtained through usual floating-point arithmetic) and the approximation of this number through our representation.
* Take as arguments the number of bits, the exact actual number (obtained through usual floating-point arithmetic) and the approximation of this number through our representation.
* Compute the error with a resolution also given as argument ((i.e. the maximum index against which error is expressed - 100 and 1000 respectively up to now).
* Compute the error with a resolution also given as argument (i.e. the maximum index against which error is expressed - 100 and 1000 respectively up to now).
However there are subtleties in the way the lines are displayed: the parts in red is supplementary text that
However there are subtleties in the way the lines are displayed: the parts in red is supplementary text that
So to do that you will need two strings arguments to provide the possibility to customize the line at the two locations pointed out in red (to achieve this you may need a reminder of [how to convert a number into a string](/notebooks/1-ProceduralProgramming/6-Streams.ipynb#Conversion)).
So to do that you will need two strings arguments to provide the possibility to customize the line at the two locations pointed out in red (to achieve this you may need a reminder of [how to convert a number into a string](/notebooks/1-ProceduralProgramming/6-Streams.ipynb#Conversion)).
Last subtlety: for the `DisplayMultiply` case we round the exact value to an integer, but that would break the output for the `TestDisplayPowerOfTwoApprox` cases... So we introduce an enum class which will act as a boolean:
Last subtlety: for the `DisplayMultiply` case we round the exact value to an integer, but that would break the output for the `TestDisplayPowerOfTwoApprox` cases... So we introduce an enum class which will act as a boolean:
````
````
enum class RoundToInteger { no, yes };
enum class RoundToInteger { no, yes };
````
````
To sum up, the signature or `print_line()` should be:
To sum up, the signature or `print_line()` should be:
````
````
void print_line(int Nbits, double exact, double approx, int maximum_error_index,
void print_line(int Nbits, double exact, double approx, int maximum_error_index,
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_