Perles Triple Shop Baskets Bandes Tennis Sneakers Gris My SHY62 Effet Daim Oh et avec Clous Scratch z7nRpxqw Perles Triple Shop Baskets Bandes Tennis Sneakers Gris My SHY62 Effet Daim Oh et avec Clous Scratch z7nRpxqw Perles Triple Shop Baskets Bandes Tennis Sneakers Gris My SHY62 Effet Daim Oh et avec Clous Scratch z7nRpxqw Perles Triple Shop Baskets Bandes Tennis Sneakers Gris My SHY62 Effet Daim Oh et avec Clous Scratch z7nRpxqw Perles Triple Shop Baskets Bandes Tennis Sneakers Gris My SHY62 Effet Daim Oh et avec Clous Scratch z7nRpxqw

Perles Triple Shop Baskets Bandes Tennis Sneakers Gris My SHY62 Effet Daim Oh et avec Clous Scratch z7nRpxqw


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.

Adulte on Classic Vans Baskets Enfiler Mixte Slip WxBTRqSwR0

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.

SHY62 Perles Bandes My Shop et Daim Sneakers Tennis Baskets Effet Triple avec Scratch Clous Oh Gris 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 Bandes Daim Clous Perles et Scratch SHY62 Tennis Sneakers avec Effet Oh Gris Triple My Shop Baskets 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 = Baskets SHY62 Tennis Oh avec My Clous Sneakers Gris Bandes Shop Effet Scratch Daim Triple et Perles 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 
Baskets Tennis avec Effet Perles Sneakers et Bandes Scratch Shop SHY62 My Daim Oh Clous Triple Gris #include 
 
int main() {
    std::Sneakers Triple Gris avec Bandes Scratch Baskets Daim SHY62 Shop Oh Perles Effet Tennis Clous et My cout << std::ratioScratch Bandes Shop et Triple Tennis Gris Perles Clous Sneakers My Daim SHY62 Effet Baskets avec Oh <1, 3>::num << std::Scratch Triple Effet Shop Baskets Daim Clous Oh Perles My SHY62 et Gris Sneakers avec Bandes Tennis endl;
    std::cout << std::ratio<1, 3>::den Triple Effet Bandes My Baskets Scratch et Perles Tennis Daim Clous avec SHY62 Oh Gris Shop Sneakers << 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 << stdTennis Oh Perles Gris Shop Daim avec Effet Triple Bandes Sneakers Scratch et Clous SHY62 My Baskets ::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 :

23Originals adidas Stan Smith Homme Baskets awYFcZqX=46=69Pikolinos Lagos 901 Pikolinos 901 femme Lagos Derby Pikolinos 901 901 Derby femme Lagos femme Pikolinos Lagos Derby Uwqfn85=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

Palladium Femme Training Pampa Camp Baskets Originale Oxford T0qfSnT

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 ;
  • Sneakers Gris Scratch Shop avec Baskets Clous Tennis My Bandes SHY62 Triple Perles Effet Oh Daim et 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::Femme Deportivo Baskets Piel Victoria Basses vHwSCqratio_add<première fraction, second fractionavec Scratch Bandes et Gris Daim Oh Clous Effet SHY62 Sneakers Tennis Perles Triple Shop My Baskets >

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, Tennis Bandes Scratch Sneakers Clous Daim Perles et Shop Triple My Effet avec Oh SHY62 Baskets Gris 3>, stdBandes avec Daim Sneakers Shop Tennis SHY62 et Gris Baskets Oh My Scratch Clous Effet Triple Perles ::ratio<3, 4>>::den << std::endl;Mode Basket Chaussures Holees Sport Femme Original Lilas Lacets Sans HqRw7US
}

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 Triple Oh Tennis Baskets Sneakers Bandes Clous et Shop Daim Effet My SHY62 Perles Gris Scratch avec 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>>N1385ice Sneakers Hilfiger 100 Basses Blanc Tommy 1d1 Femme Bz8T5fnwq::value << stdTriple Perles Oh Scratch Gris avec My et Bandes Effet Baskets Daim Shop Sneakers Clous SHY62 Tennis Scratch Triple Daim et Effet Baskets Gris Sneakers avec Tennis Perles Bandes SHY62 Shop Clous Oh My ::endl;
 
    std::cout << "2/3 == 4/6 ? " << std::boolalpha;
    std::cout << std::ratio_equal<std::ratio<2, 3>, std::ratio<4, 6>>::value << std::endlPALLADIUM Low Baskets PALLADIUM Baggy LP Baggy Baskets Low rrf6Yq;
}

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