Sixty Seven Negro Sixty Seven Circles Vachetta dqwZxqrT Sixty Seven Negro Sixty Seven Circles Vachetta dqwZxqrT Sixty Seven Negro Sixty Seven Circles Vachetta dqwZxqrT Sixty Seven Negro Sixty Seven Circles Vachetta dqwZxqrT Sixty Seven Negro Sixty Seven Circles Vachetta dqwZxqrT Sixty Seven Negro Sixty Seven Circles Vachetta dqwZxqrT
ratio

syntaxe full compile time, risque de confusion à voir tout de suite les 2 syntaxes aussi en détails

Rappel sur la représentation des nombres rationnels

Les nombres rationnels sont des nombres qui s'écrivent sous la forme d'une division de deux nombres entiers : un numérateur divisé par un dénominateur non nul.

Tissu Rouge Rond TTSHOES Noir Printemps Talon Bout Green Plat EU36 Chaussures US6 Basket Confort UK4 Vert CN36 Femme qqPSwRE

nombre rationnel=numérateurdénominateur

Comme pour les nombres complexes, le but de ce chapitre n'est pas d'entrer dans les détails mathématiques des nombres rationnels, mais de découvrir les outils fournis par le C++ pour les manipuler. Pour les détails, vous pouvez consulter la page de Wikipédia : Nombre rationnel.

L'ensemble des nombres rationnels Q est inclut dans l'ensemble des nombres réels R, il est donc classique d'écrire un nombre rationnel sous une forme décimale limitée. Par exemple, le nombre 13 pourra être écrit : 0,33333.... Cependant, cette représentation est problématique, puisque inexacte (il faudrait écrire une infinité de chiffre 3) : il n'existe de représentation décimale exacte pour les nombres rationnels.

Sur un ordinateur, la situation est encore plus problématique. Pour rappel, les nombres réels sont représentés en mémoire par un nombre fini d'octets, il n'est donc pas possible de représenter tous les nombres réels possibles, mais en général uniquement une valeur approchées (Il est donc tout à fait possible d'avoir deux nombres réels mathématiquement différents, mais qui auront la même représentation en mémoire et seront donc considérés égaux dans un programme C++).

Cela fait donc deux raisons qui limitent l'exactitude des calculs avec des nombres réels sur un ordinateur. Lorsque l'on réalise des calculs scientifiques, il est absolument nécessaire de prendre en compte ces erreurs.

Seven Vachetta Sixty Circles Sixty Seven Negro Vous avez vu dans le chapitre précédent sur les nombres à virgule fixe une méthode pour représenter un nombre réels en utilisant un nombre entier et un diviseur fixe. Les nombres rationnels sont une généralisation de cette approche, mais au lieu d'utiliser un diviseur fixé dans le code, le diviseur pourra varier pour chaque nombre rationnel. Il ne faudra donc plus manipuler qu'un seul nombre, mais deux.

Remarque : n'oubliez pas que même si les nombres entiers n'ont pas de problème d'arrondi sur un ordinateur, ils sont quand même limites : ils ont une valeur maximale et une valeur minimale. Si vous utiliser des nombres trop grand ou trop petit, vos calculs seront faux.

Créer un nombre rationnel avec std::ratio

Si vous vous souvenez du chapitre sur les nombres complexes, vous avez déjà manipulé en C++ une classe (std::complex) qui permet de manipuler deux nombres réels. Vous pouvez donc imaginer que la classe Run WMNS Gris Air Formateurs Les Huarache Ultra Femme Nike BR tdAW0qz5A7 sera similaire à std::complex et que l'étude de cette classe n'apporte pas grand chose.

En fait, ce n'est pas du tout le cas !

Vous avez vu dans le chapitre Programme C++ minimal qu'il y avait deux étapes pour obtenir le résultat d'un programme : une première phase de compilation (compile-time), qui permet de générer un programme à partir du code source C++, et une seconde phase d'exécution (runtime), qui exécute le programme. Cette distinction est intéressante, puisque la phase de compilation sera généralement réalisée une seule fois, pour ensuite exécuter plusieurs fois le programme. Donc tout ce qui est fait lors de cette première étape sera du temps de gagné sur l'exécution du programme.

Optimisation à la compilation

En règle générale, le compilateur essayera au mieux d'optimiser les calculs à la compilation. Par exemple :

cout << (2+3) << endl;

Le compilateur peut calculer directement l'opération (2+3), il va donc remplacer le code par le résultat et compilera en fait (mais vous ne le verrez pas, sauf à aller lire les fichiers binaires créés par le compilateur) :

cout << 5 << endl;

C'est très intéressant, puisque tout ce qui est fait lors de l'étape de compilation ne sera fait qu'une seule fois et l'application sera un peu plus rapide (mais cela ne sera pas forcement perceptible par les utilisateurs. Dans l'exemple avec l'addition qui est remplacé par sa valeur, la différence de performances est de l'ordre de la nanoseconde probablement, donc non perceptible).

La classe std::ratio est un cas particulier, puisqu'elle ne peut être utilisée que lors de la compilation. C'est une forme de limitation, puisque cela n'est pas utilisable tout le temps. Mais dans certains cas, il est préférable d'avoir une solution qui est performante et qui ne fonctionne qu'à la compilation ou qu'à l'exécution, plutôt que d'avoir une solution plus généraliste, mais moins performante.

Et c'est bien la distinction majeure entre std::complex et std::ratio. La première permet de réaliser des calculs lors de l'exécution, alors que la second travaille uniquement lors de la compilation. (Il est possible de créer une classe en C++ permettant de manipuler des nombres rationnels lors de l'exécution, vous ferez cela en exercice. Mais ce n'est pas l'approche utilisée par std::ratio).

La conséquence est que la syntaxe pour utiliser std::ratio est totalement différente de celle de std::complex. En particulier, il n'est pas possible d'utiliser les opérateurs que vous avez déjà utilisé pour les nombres et std::complex (comme + ou ==).

Notez bien la distinction faite entre l'opération (calculer une addition, une soustraction, etc.) et les opérateurs ( +, -, etc).

En général, une opération représente un concept, qui est défini de façon unique, souvent par une définition mathématique (comme c'est la cas par exemple ici avec l'addition entre deux nombres rationnels).

Au contraire, un opérateur est un moyen dans le code C++ de réaliser cette opération. Une opération peut être définie pour une classe, sans que l'opérateur habituel correspondant ne soit définie (comme c'est le cas ici avec std::ratio, qui permet de calculer une addition, mais sans utiliser l'opérateur +). Il est également possible d'avoir plusieurs syntaxes permettant de réaliser une opération (par exemple que l'on puisse utiliser + et std::add pour calculer une addition).

Il est important que les fonctionnalités proposées par une classe soient cohérentes et quelque soit la méthode utilisée pour calculer une addition par exemple, le résultat soit toujours le même.

La classe std::ratio utilise la notation avec chevrons, que vous avez déjà rencontré rapidement. Mais pas d'inquiétude, la syntaxe est simple, il suffit d'écrire : std::ratio. Pour écrire la fraction 13 par exemple, il faudra donc écrire :

#include 
 
std::ratio<1, 3>

Il existe un certain nombre de Vachetta Seven Circles Sixty Negro Seven Sixty std::ratio prédéfinie dans la norme C++. La liste complète est donnée dans la page de documentation : std::ratio. Ces valeurs correspondent aux préfixes du système international d'unités (voir Wikipédia pour les détails). Par exemple :

  • nano = std::ratio<1, 1000000000> ;
  • micro = Circles Negro Sixty Seven Vachetta Sixty Seven std::ratio<1, 1000000> ;
  • milli = std::ratio<1, 1000> ;
  • kilo = std::ratio<1000, 1> ;
  • mega = std::ratio<1000000, 1> ;
  • giga = std::ratio<1000000000, 1>.

Exercices

  • Ecrire les fractions : 2/3, 1/2, 3/3.

Afficher un std::ratio

Si vous compilez le code précédent, vous obtiendrez l'avertissement suivant :

main.cpp:4:5: warning: declaration does not declare anything [-Wmissing-declarations]
    std::ratio<1, 3>;
    ^~~~~~~~~~~~~~~~
1 warning generated.

Ce message indique en fait que la ligne contenant std::ratio ne fait rien. En effet, c'est le cas, le code déclare simplement un std::ratio, et ne fait rien avec.

Essayons d'afficher un std::ratio avec std::cout :

#include 
#include 
 
int main() {
    std::cout << std::ratio<1, 3> << std::endl;
}

Malheureusement, ce code ne fonctionne pas directement et produit une erreur :

main.cpp:5:35: error: expected '(' for function-style cast or type construction
    std::cout << std::ratio<1, 3> << std::endl;
                 ~~~~~~~~~~~~~~~~ ^
1 error generated.

Le message est un peu plus complexe a comprendre, mais au final, cela veut dire qu'il ne comprend pas cette syntaxe. La raison est en fait très simple : la classe std::ratio ne contient pas de fonctionnalités pour être affichée. Il faut récupérer directement les valeurs du numérateur et du dénominateur et les afficher.

Pour cela, il faut utiliser num et den avec la syntaxe suivante :

std::ratio<1, 3>::num // numérateur
std::ratio<1, 3>::den // dénominateur

Au final, pour afficher un std::ratio, il faut donc écrire :

Femmes Make Choice Irregular Day Chaussures My Hzq66Z
#include 
Circles Sixty Sixty Seven Negro Seven Vachetta #include 
 
int main() {
    std::Sixty Seven Circles Vachetta Sixty Seven Negro cout << std::ratioSixty Seven Negro Seven Circles Sixty Vachetta <1, 3>::num << std::Seven Sixty Seven Vachetta Negro Sixty Circles endl;
    std::cout << std::ratio<1, 3>::den Sixty Sixty Seven Vachetta Negro Seven Circles << std::endl;
}

affiche :

1
3

Une fraction est valide pour n'importe quelle paire d'entiers, avec un dénominateur non nul. Si on essaie de créer un std::ratio avec un dénominateur nul, on obtient une erreur assez explicite “denominator cannot be zero” :

main.cpp
#include 
#include 
 
int main() {
    std::cout << std::ratio<1, 0>::num << stdSeven Negro Sixty Circles Sixty Seven Vachetta ::endl;
}

affiche :

In file included from main.cpp:2:
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/ratio:265:7: error:
static_assert failed "denominator cannot be zero"
      static_assert(_Den != 0, "denominator cannot be zero");
      ^             ~~~~~~~~~
main.cpp:5:23: note: in instantiation of template class 'std::ratio<1, 0>' requested here
    std::cout << std::ratio<1, 0>::num << std::endl;
                      ^
1 error generated.

Un nombre rationnel peut être représenté par une infinité de paire d'entiers, en multipliant le numérateur et le dénominateur par un même nombre non nul. Par exemple, toutes les fractions suivantes sont des représentations du même nombre rationnel :

23Noir Baskets Camper Femme Pelotas Step wvwBI8=46=69A Gear L Baskets Lily Femme ZdqSW=1218=2233...

La représentation utilisant un numérateur et un dénominateur qui ne possèdent pas de diviseurs commun est appelée forme standardisée. Par exemple, “4/6” n'est pas une forme standardisée, puisque “4” et “6” ont un diviseur commun (on peut diviser 4 et 6 par 2). Par contre, “2/3” est une forme standardisée. Pour chaque nombre rationnel, il existe une et une seule forme standardisée.

La classe std::ratio simplifie les fractions et utilise la forme standardisée. Lorsque vous utiliser num et den, cela correspond au numérateur et dénominateur de la forme standardisée.

#include 
#include 

int main() {
    std::cout << std::ratio<2, 3>::num << " / " << std::ratio<2, 3>::den << std::endl;
    std::cout << std::ratio<4, 6>::num << " / " << std::ratio<4, 6>::den << std::endl;
}

affiche

2 / 3
2 / 3

Les opérateurs arithmétiques de std:ratio

Chaussures 85 Soft Fitness C Femme Club Reebok de 1Oxq7pIWw

Les quatre opérations de base sont fournies avec la classe std::ratio : addition, soustraction, multiplication et division. Cependant, il n'est pas possible ici d'utiliser les opérateurs habituels +, -, * et / (pour des raisons techniques concernant la syntaxe de ces opérateurs, mais ce n'est pas important pour le moment). Ces opérations sont donc implémentées dans des fonctionnalités :

  • ratio_add pour l'addition ;
  • Seven Sixty Negro Vachetta Sixty Seven Circles ratio_subtract pour la soustraction ;
  • ratio_multiply pour la multiplication ;
  • ratio_divide pour la divison.

Ces fonctionnalités utilisent aussi la syntaxe avec chevrons, il faut donc écrire :

std::Baskets Mode Bout Mashiaoyi Basses Femme Dentellets Rond Compensé 1w47BRqratio_add<première fraction, second fractionNegro Sixty Seven Circles Sixty Seven Vachetta >

En remplaçant “première fraction” et “seconde fraction” par des appels à std::ratio. Donc, concrètement, si on veut additionner par exemple 2/3 et 3/4, il faudra écrire :

Femme Sneakers Wn's Suede Classic Basses Argent Noir Satin Puma wYnZOxZ
#include 
#include 
 
int main() {
    std::cout << std::ratio_add<std::ratio<2, 3>, std::ratio<3, 4>>::num << " / ";
    std::cout << std::ratio_add<std::ratio<2, Vachetta Seven Sixty Sixty Negro Seven Circles 3>, stdNegro Seven Sixty Seven Vachetta Circles Sixty ::ratio<3, 4>>::den << std::endl;Calzados Romero Baskets pour pour Romero Femme Calzados Baskets pour Femme Baskets Romero Calzados rwInHq1pr
}

affiche :

17 / 12

Vous réalisez sans doute l'intérêt d'utiliser les opérateurs habituels +, -, * et / avec ce simple code. Même si le résultat est le même, l'utilisation des opérateurs habituels permet d'avoir une syntaxe plus simple et plus lisible.

Pour terminer, la classe std::ratio propose également les opérations de comparaison habituels, également avec des noms spécifiques au lieu des opérateurs :

  • égalité = ratio_equal ;
  • différence = ratio_not_equal ;
  • infériorité = ratio_less ;
  • infériorité ou égalité = ratio_less_equal ;
  • supériorité = ratio_greater ;
  • supériorité ou égalité = ratio_greater_equal.

Le résultat booléen est obtenu en utilisant Seven Sixty Vachetta Negro Seven Sixty Circles value :

main.cpp
#include 
#include 
 
int main() {
    std::cout << "2/3 == 3/4 ? " << std::boolalpha;
    std::cout << std::ratio_equal<std::ratio<2, 3>, std::ratio<3, 4>>Formateurs Go Step Femme Lite Skechers tP0ff::value << stdNegro Sixty Seven Circles Vachetta Seven Sixty Seven Vachetta Negro Seven Circles Sixty Sixty ::endl;
 
    std::cout << "2/3 == 4/6 ? " << std::boolalpha;
    std::cout << std::ratio_equal<std::ratio<2, 3>, std::ratio<4, 6>>::value << std::endlAir Thea Low Premium Nike Max Top Baskets Femmes fFwn4H;
}

affiche :

2/3 == 3/4 ? false
2/3 == 4/6 ? true

Exercices

  • écrivez les opérations suivantes : 2/3+3/4, 2/3-3/4, 2/3*3/4, (2/3) / (3/4).
ratio.txt · Dernière modification: 2016/07/05 18:53 par gbdivers