Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
calculs_arithmetiques [2015/07/28 16:34] 86.195.9.232 [Exercices] |
calculs_arithmetiques [2019/01/04 20:43] (Version actuelle) nico [Les nombres décimaux, hexadécimaux, octaux et binaires] |
||
---|---|---|---|
Ligne 8: | Ligne 8: | ||
* les nombres entiers : ''0'', ''1'', ''2'', ''-1'', ''-2'' ; | * les nombres entiers : ''0'', ''1'', ''2'', ''-1'', ''-2'' ; | ||
* les nombres réels : ''1.0'', ''2.1'', ''-5.12'', ''1.457'' ; | * les nombres réels : ''1.0'', ''2.1'', ''-5.12'', ''1.457'' ; | ||
- | * les booléens, qui représente une valeur à deux états : ''true'' (vrai) et ''false'' (faux) ; | + | * les booléens, qui représentent une valeur à deux états : ''true'' (vrai) et ''false'' (faux) ; |
* les caractères : 'a', 'b', 'c' ; | * les caractères : 'a', 'b', 'c' ; | ||
* les chaînes de caractères (que vous avez déjà vu) : "hello, world", "salut tout le monde". | * les chaînes de caractères (que vous avez déjà vu) : "hello, world", "salut tout le monde". | ||
Ligne 22: | Ligne 22: | ||
std::cout << 1 << std::endl; // nombre entier | std::cout << 1 << std::endl; // nombre entier | ||
std::cout << 3.1415 << std::endl; // nombre réel | std::cout << 3.1415 << std::endl; // nombre réel | ||
- | std::cout << true << std::endl; // booléens | + | std::cout << true << std::endl; // booléen |
std::cout << 'a' << std::endl; // caractère | std::cout << 'a' << std::endl; // caractère | ||
std::cout << "hello, world!" << std::endl; // chaîne de caractères | std::cout << "hello, world!" << std::endl; // chaîne de caractères | ||
Ligne 28: | Ligne 28: | ||
</code> | </code> | ||
- | Nous reviendrons par la suite sur les spécificités de chaque type de littérales, voyons pour le moment les nombres entiers plus en détail. | + | Nous reviendrons par la suite sur les spécificités de chaque type de littérale, voyons pour le moment les nombres entiers plus en détail. |
===== Écrire des nombres entiers ===== | ===== Écrire des nombres entiers ===== | ||
Ligne 108: | Ligne 108: | ||
</code> | </code> | ||
- | Vous pouvez écrire des nombres très grand de cette manière, mais il existe une limite. Si vous écrivez un nombre trop grand, vous aurez un message d'erreur signalant que ce nombre est trop grand. | + | Vous pouvez écrire des nombres très grands de cette manière, mais il existe une limite. Si vous écrivez un nombre trop grand, vous aurez un message d'erreur signalant que ce nombre est trop grand. |
<code cpp main.cpp> | <code cpp main.cpp> | ||
Ligne 128: | Ligne 128: | ||
L’existence d'une valeur maximale limite est liée à la représentation des nombres dans la mémoire des ordinateurs et à la notion de type de données. Vous verrez cela dans les prochains chapitres. | L’existence d'une valeur maximale limite est liée à la représentation des nombres dans la mémoire des ordinateurs et à la notion de type de données. Vous verrez cela dans les prochains chapitres. | ||
- | <note info>Il existe des outils qui permettent d'utiliser des nombres avec autant de chiffre que vous souhaitez, mais il ne sera pas possible d'utiliser dans ce cas les nombres entiers tel que définit dans ce chapitre. Vous verrez par la suite quelques bibliothèques qui permettent de faire cela et pourrez implémenter ce type de fonctionnalités.</note> | + | <note info>Il existe des outils qui permettent d'utiliser des nombres avec autant de chiffres que vous souhaitez, mais il ne sera pas possible d'utiliser dans ce cas les nombres entiers tel que définis dans ce chapitre. Vous verrez par la suite quelques bibliothèques qui permettent de faire cela et pourrez implémenter ce type de fonctionnalités.</note> |
===== Les nombres décimaux, hexadécimaux, octaux et binaires ===== | ===== Les nombres décimaux, hexadécimaux, octaux et binaires ===== | ||
Ligne 134: | Ligne 134: | ||
Les nombres entiers que vous utilisez habituellement s'écrivent à partir de dix chiffres (0 à 9). C'est pour cette raison que l'on parle de système décimal (du latin //decimus//, qui signifie "dixième") et de base 10. Mais ce n'est pas la seule façon d'écrire les nombres et il existe d'autres systèmes numériques. | Les nombres entiers que vous utilisez habituellement s'écrivent à partir de dix chiffres (0 à 9). C'est pour cette raison que l'on parle de système décimal (du latin //decimus//, qui signifie "dixième") et de base 10. Mais ce n'est pas la seule façon d'écrire les nombres et il existe d'autres systèmes numériques. | ||
- | Imaginons par exemple que vous souhaitez écrire des nombres en utilisant que huit chiffres (0 à 7 - base 8). Dans ce cas, nous pouvons compter de la façon suivante : 0, 1, 2, 3, 4, 5, 6, 7. Arrivé au huitième chiffre, nous ne pouvons pas écrire "8", puisque ce chiffre n'est pas autorisé dans ce système. Donc, il faut passer à un nombre à deux chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, etc. | + | Imaginons par exemple que vous souhaitez écrire des nombres en n'utilisant que huit chiffres (0 à 7 - base 8). Dans ce cas, nous pouvons compter de la façon suivante : 0, 1, 2, 3, 4, 5, 6, 7. Arrivé au huitième chiffre, nous ne pouvons pas écrire "8", puisque ce chiffre n'est pas autorisé dans ce système. Donc, il faut passer à un nombre à deux chiffres : 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, etc. |
- | En C++, il est possible d'écrire et afficher des nombres écrits selon des bases différentes de 10. Pour des raisons historiques et matériel, les ordinateurs savent manipuler les nombres en base 2 (binaire), 8 (octal), 10 (décimal) et 16 (hexadécimal). Pour écrire un nombre dans une base différente de 10, il faut commencer le nombre par le chiffre 0 puis un caractère optionnel pour spécifier la base : rien pour octal, ''x'' ou ''X'' pour l'hexadécimal et ''b'' pour le binaire. Les chiffres autorisés pour écrire un nombre dépendent de la base utilisée : 0 à 7 pour l'octal, 0 à 9 et a à f (ou A à F) pour l'hexadécimal et 0 et 1 pour le binaire. | + | En C++, il est possible d'écrire et afficher des nombres écrits selon des bases différentes de 10. Pour des raisons historiques et matérielles, les ordinateurs savent manipuler les nombres en base 2 (binaire), 8 (octal), 10 (décimal) et 16 (hexadécimal). Pour écrire un nombre dans une base différente de 10, il faut commencer le nombre par le chiffre 0 puis un caractère optionnel pour spécifier la base : rien pour octal, ''x'' ou ''X'' pour l'hexadécimal et ''b'' pour le binaire. Les chiffres autorisés pour écrire un nombre dépendent de la base utilisée : de 0 à 7 pour l'octal, de 0 à 9 pour la décimal et de a à f (ou A à F) pour l'hexadécimal et 0 et 1 pour le binaire. |
Le code suivant permet d'afficher la valeur de 10 selon la base : | Le code suivant permet d'afficher la valeur de 10 selon la base : | ||
Ligne 160: | Ligne 160: | ||
</code> | </code> | ||
- | Il est possible réaliser ces conversions à la main, mais c'est plus simple d'utiliser un logiciel de conversion. Il existe des convertisseurs en ligne, vous pouvez également utiliser la calculatrice de Windows en sélectionnant le mode "Programmeur" dans le menu "Affichage". | + | Il est possible de réaliser ces conversions à la main, mais c'est plus simple d'utiliser un logiciel de conversion. Il existe des convertisseurs en ligne, vous pouvez également utiliser la calculatrice de Windows en sélectionnant le mode "Programmeur" dans le menu "Affichage". |
{{ :calculatrice.png |}} | {{ :calculatrice.png |}} | ||
Ligne 264: | Ligne 264: | ||
<note>Faites bien la distinction entre l'opération écrite entre guillemets "123 + 456", qui est donc interprétée comme une chaîne de caractères et non évaluée, et la même chose en dehors des guillemets, qui sera interprétée comme une expression mathématique et évaluée.</note> | <note>Faites bien la distinction entre l'opération écrite entre guillemets "123 + 456", qui est donc interprétée comme une chaîne de caractères et non évaluée, et la même chose en dehors des guillemets, qui sera interprétée comme une expression mathématique et évaluée.</note> | ||
- | Il est également possible de calculer des divisions entières avec l'opérateur division ''/'' et de calculer le reste d'une division entière avec l'opérateur modulo ''%''. Pour rappel, la division entière permet de calculer le résultat d'une division en utilisant uniquement des nombres entiers (c'est le premier type de division que vous avez appris à l'école). Ainsi : | + | Il est également possible de calculer des divisions entières avec l'opérateur division ''/'' et de calculer le reste d'une division entière avec l'opérateur ''%'' (cette opération s'appelle le "modulo"). Pour rappel, la division entière permet de calculer le résultat d'une division en utilisant uniquement des nombres entiers (c'est le premier type de division que vous avez appris à l'école). |
- | * avec une division entière : 11 divisé par 4 donne 2 et reste 3 ; | + | {{ :division.png?150 |}} |
- | * avec une division réelle : 11 divisé par 4 donne 2,75. | + | |
+ | En orange, le dividende. En bleu, le diviseur. En vert, le quotient (le résultat de la division entière). Et en jaune, le reste de la division (le modulo). Une division entière peut se réécrire sous forme d'une multiplication et d'une addition: | ||
+ | |||
+ | $$ 1234 = 56 \times 22 + 2 $$ | ||
+ | |||
+ | Et plus généralement, le reste d'une division entière est le nombre entier qui respecte l'équation suivante (toutes les variables étant des entiers), de façon a ce que le reste est compris entre 0 et le quotient-1. | ||
+ | |||
+ | $$ \text{dividende}= \text{diviseur}\times \text{quotient}+ \text{reste}\qquad (\text{avec} ~ 0 \leq \text{reste}< \text{quotient}) $$ | ||
+ | |||
+ | La division réelle retourne un nombre réel : | ||
+ | |||
+ | * avec une division entière : 1234 divisé par 56 donne 22 et reste 2 ; | ||
+ | * avec une division réelle : 1234 divisé par 56 donne 22,0357. | ||
<code cpp main.cpp> | <code cpp main.cpp> | ||
Ligne 295: | Ligne 307: | ||
<note>En C++, l'opérateur ''/'' est utilisé pour faire les divisions entières et réelles. Il faut donc particulièrement faire attention de ne pas se tromper lorsque l'on écrit une expression, sous peine d'avoir des résultats étranges. | <note>En C++, l'opérateur ''/'' est utilisé pour faire les divisions entières et réelles. Il faut donc particulièrement faire attention de ne pas se tromper lorsque l'on écrit une expression, sous peine d'avoir des résultats étranges. | ||
+ | |||
+ | Le type de division (réelle ou entière) sera déterminé par le type des valeurs que vous utilisez : si les deux valeurs sont entières, cela sera une division entière. Si au moins une des deux valeurs est réelle, alors cela sera une division réelle. | ||
<code cpp main.cpp> | <code cpp main.cpp> | ||
Ligne 300: | Ligne 314: | ||
int main() { | int main() { | ||
- | std::cout << "11 / 4 = " << 11 / 4 << std::endl; // division entière | + | std::cout << "11 / 4 = " << 11 / 4 << std::endl; // division entière |
std::cout << "11.0 / 4.0 = " << 11.0 / 4.0 << std::endl; // division réelle | std::cout << "11.0 / 4.0 = " << 11.0 / 4.0 << std::endl; // division réelle | ||
+ | std::cout << "11 / 4.0 = " << 11 / 4.0 << std::endl; // division réelle | ||
+ | std::cout << "11.0 / 4 = " << 11.0 / 4 << std::endl; // division réelle | ||
} | } | ||
</code> | </code> | ||
Ligne 308: | Ligne 324: | ||
<code> | <code> | ||
- | 11 / 4 = 2 | + | 11 / 4 = 2 |
11.0 / 4.0 = 2.75 | 11.0 / 4.0 = 2.75 | ||
+ | 11 / 4.0 = 2.75 | ||
+ | 11.0 / 4 = 2.75 | ||
</code> | </code> | ||
+ | |||
+ | Comme vous le voyez dans ce code d'exemple, les nombres réelles sont écrit avec un point en C++ (notation anglaise) et non une virgule (comme en français). | ||
</note> | </note> | ||
Ligne 332: | Ligne 352: | ||
De la même façon, les opérateurs du C++ suivent les règles arithmétiques habituelles : | De la même façon, les opérateurs du C++ suivent les règles arithmétiques habituelles : | ||
- | * la commutativité (sauf pour la division) : a + b = b + a ; | + | * la commutativité : a + b = b + a (uniquement pour l'addition et la multiplication) ; |
* l'associativité : a + (b + c) = (a + b) + c ; | * l'associativité : a + (b + c) = (a + b) + c ; | ||
* la distributivité : a * (b + c) = a * b + a * c. | * la distributivité : a * (b + c) = a * b + a * c. | ||
Ligne 390: | Ligne 410: | ||
</code> | </code> | ||
- | On parle en C++ de "comportement indéfini", //undefined behavior// en anglais, que l'on abrège parfois avec les initiales "UB". Cela signifie qu'un programme utilisant un tel code aura un comportement aléatoire et pourra faire n'importe quoi : provoquer une erreur, donner un résultat quelconque ou encore sembler fonctionner correctement. Les comportements indéfinis sont difficile à corriger, puisque cela ne produit pas forcement un message d'erreur clair. | + | On parle en C++ de "comportement indéfini", //undefined behavior// en anglais, que l'on abrège parfois avec les initiales "UB". Cela signifie qu'un programme utilisant un tel code aura un comportement aléatoire et pourra faire n'importe quoi : provoquer une erreur, donner un résultat quelconque ou encore sembler fonctionner correctement. Les comportements indéfinis sont difficiles à corriger, puisque cela ne produit pas forcement un message d'erreur clair. |
- | Ainsi, l'exécution du programme précédent se déroule sans erreur à l'exécution. Par contre, la valeur affichée par ''std::cout'' est aléatoire (dans Coliru.com) et n'a pas de sens en termes mathématiques : | + | Ainsi, l'exécution du programme précédent se déroule sans erreur à l'exécution. Par contre, la valeur affichée par ''std::cout'' est aléatoire (dans coliru.com) et n'a pas de sens en termes mathématiques : |
<code> | <code> | ||
Ligne 404: | Ligne 424: | ||
Ce cours de C++ n'a pas pour vocation à vous apprendre tout le C++. Il se focalise, volontairement, sur les syntaxes les plus récentes et les plus sûres. Et même en utilisant ces approches modernes, il y aura des précautions à prendre pour éviter les problèmes. Vous apprendrez à écrire du code le plus sécurisé possible. | Ce cours de C++ n'a pas pour vocation à vous apprendre tout le C++. Il se focalise, volontairement, sur les syntaxes les plus récentes et les plus sûres. Et même en utilisant ces approches modernes, il y aura des précautions à prendre pour éviter les problèmes. Vous apprendrez à écrire du code le plus sécurisé possible. | ||
- | **Faites vous aider par le compilateur**. Celui-ci peut faire certaine vérifications, comme dans le code précédent, et vous avertir lorsque vous écrivez un code qui pose potentiellement un problème. Tous les compilateurs ne font pas les mêmes vérifications et les contrôles effectués dépendent des options utilisées. Les options ''-Wall -Wextra -pedantic'' qui vous ont été présenté dans coliru.com activent les principales vérifications, mais il en existe d'autres. Il peut être intéressant de compiler un code avec plusieurs compilateurs pour avoir un maximum de messages d'avertissement. | + | **Faites vous aider par le compilateur**. Celui-ci peut faire certaines vérifications, comme dans le code précédent, et vous avertir lorsque vous écrivez un code qui pose potentiellement un problème. Tous les compilateurs ne font pas les mêmes vérifications et les contrôles effectués dépendent des options utilisées. Les options ''-Wall -Wextra -pedantic'' qui vous ont été présentés dans coliru.com activent les principales vérifications, mais il en existe d'autres. Il peut être intéressant de compiler un code avec plusieurs compilateurs pour avoir un maximum de messages d'avertissement. |
- | **Utilisez les outils de vérifications statique et dynamique**. Ce sont des outils qui font plus de vérifications que le compilateur. Les premiers vérifient le code directement, alors que les seconds travaillent sur le programme après compilation (donc durant l'exécution). | + | **Utilisez les outils de vérification statique et dynamique**. Ce sont des outils qui font plus de vérifications que le compilateur. Les premiers vérifient le code directement, alors que les seconds travaillent sur le programme après compilation (donc durant l'exécution). |
Non seulement ils permettent de vérifier le respect des règles du langage C++, mais également que certaines pratiques de codage sont respectées. Dans l'objectif d'écrire des programmes C++ modernes, il ne faut pas hésiter à utiliser ce type d'outils. Vous verrez dans la suite de ce cours comment installer et utiliser certains de ces outils. | Non seulement ils permettent de vérifier le respect des règles du langage C++, mais également que certaines pratiques de codage sont respectées. Dans l'objectif d'écrire des programmes C++ modernes, il ne faut pas hésiter à utiliser ce type d'outils. Vous verrez dans la suite de ce cours comment installer et utiliser certains de ces outils. | ||
- | ===== Exercices ===== | + | ^ [[doc|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[logique_et_calcul_booleen|Chapitre suivant]] ^ |
- | __ cf http://openclassrooms.com/forum/sujet/exercices-dans-le-cours-de-gbdivers __ | ||
- | |||
- | Remarque : le but de ces exercices est de faire des calculs arithmétiques de base. C'est assez simple, ce n'est pas vraiment de la programmation (c'est surtout pour jouer avec l'affichage et les opérations de base). Mais c'est quelque chose que l'on doit savoir faire (même à la main, avec crayon et papier) | ||
- | |||
- | ** Conversion en nombre de n'importe quelle base ** | ||
- | |||
- | http://fr.wikipedia.org/wiki/Syst%C3%A8me_d%C3%A9cimal | ||
- | |||
- | opérations à faire pour les calculs ? | ||
- | |||
- | Le but de cet exercice est de convertir un nombre d'une base donnée en une autre base. (comme c'est le début du cours, il ne faudra utiliser que les opérations mathématiques et l'affichage, donc pas de boucles et fonctions). Par exemple convertir 1234 en hexadécimal ou 0xabc en décimal. (le but est de pratiquer les conversions de bases, pas d'écrire un code de conversion réutilisable). Tu peux prendre n'importe quel nombre dans n'importe quelle base (en utilisant les préfixes), l'afficher dans une autre base (en utilisant std::hex, std::dec, etc), puis ecrire un code qui affiche la conversion, mais faite manuellement. | ||
- | |||
- | ** Calculer l'indice de colonne et de ligne d'une table ** | ||
- | |||
- | Cet exercice consiste à calculer la ligne et la colonne correspondant à un index donné (c'est très utile pour les tableaux à plusieurs dimensions). Pour cet exo, imaginez un tableau suivant : | ||
- | |||
- | <code> | ||
- | 0 1 2 3 | ||
- | 4 5 6 7 | ||
- | 8 9 10 11 | ||
- | </code> | ||
- | |||
- | (on appelle ce tableau "row major" puisque les données sont en ligne en premier, cf http://en.wikipedia.org/wiki/Row-major_order). Si on donne un élément du tableau (par exemple 6), il faut trouver le numéro de ligne et le numéro de colonne correspondant, en utilisant les opérateurs / et %. Faire de même avec d'autres tableaux (dont des tableaux en column major). Remarque : en C++, on compte à partir de 0. Donc les colonnes et lignes s'écrivent 0, 1, 2, ... (et pas 1, 2, 3, ...) | ||
- | |||
- | Préliminaire : Je veux l'indice du tableau 1D qui correspond à la case (x,y) de mon tableau 2D, sachant que j'ai rangé mes lignes l'une derrière l'autre, d'abord la première ligne, ensuite la seconde ... | ||
- | |||
- | Pour la découvrir empiriquement, quelle est l'indice de la première colonne de la première ligne? Quel est l'indice de la dernière colonne de la première ligne? Quel est l'indice de la première colonne de la seconde ligne? quelle est l'indice de la dernière colonne de la seconde ligne?, quel est l'indice de la dernière colonne de la dernière ligne?, Quel est l'indice de la première colonne de la dernière ligne? et pour finir quel est l'indice d'une case (x,y) quelconque du tableau 2D? | ||
- | |||
- | Sachant qu'a chaque indice du tableau 1D il y a une seule position (x,y) qui correspond, et que chaque position (x,y) correspond un seul indice du tableau 1D, si tu connais la formule dans un sens, découvrir la formule dans l'autre sens ne sera pas très difficile ;). | ||
- | |||
- | A partir d'un élément du tableau (par exemple i = 6, i pour index), tu as besoin de connaitre la largeur (w = 4, w pour width) et la hauteur (h = 3, h pour height) du tableau et d'utiliser les opérateurs division entière / et modulo %. Tu dois obtenir pour i = 6, x = 2 (numéro de colonne) et y = 1 (numéro de ligne). | ||
- | |||
- | Si ta formule est bonne, cela veut dire qu'en appliquant la même formule sur un autre indice du tableau ou un autre tableau, le numéro de ligne et de colonne devraient être bons. Est-ce que c'est le cas ? Essaie par exemple, avec le même tableau, avec l'indice 7 par exemple (cela doit donner ligne=1 et colonne=3) | ||
- | |||
- | Remarque : Une division entière (comme on l'apprend en primaire : image) peut s’écrire : | ||
- | |||
- | <code> | ||
- | dividende = diviseur * quotient + reste | ||
- | </code> | ||
- | |||
- | La division entière et le modulo sont les opérations qui permettent d'avoir le quotient et le reste : | ||
- | |||
- | <code> | ||
- | division(dividande, diviseur) = quotient | ||
- | modulo(dividande, diviseur) = reste | ||
- | </code> | ||
- | |||
- | En C++, on va écrire : | ||
- | |||
- | <code> | ||
- | std::cout << "Quotient = " << (dividende / diviseur) << std::endl; | ||
- | std::cout << "Reste = " << (dividende % diviseur) << std::endl; | ||
- | </code> | ||
- | |||
- | ** Des compteurs finis ** | ||
- | |||
- | Un autre exercice avec modulo : imaginons que l'on a un compteur qui compte jusqu'à 100. Comment transformer ce compteur en compteur qui compte de 0 à 10 en boucle ? (il doit retourner 0, 1, ..., 8, 9, 0, 1, ...) | ||
- | |||
- | Faire de même pour compter de 3 à 8 en boucle. | ||
- | |||
- | ^ [[doc|Chapitre précédent]] ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ [[logique_et_calcul_booleen|Chapitre suivant]] ^ |