Programmation C++

Cours de Licence Professionnelle SIL IN - IUT de Provence, site d'Arles


Planche de TP n°1 : La classe Ratio

Dans ce TP, nous nous proposons de développer une classe C++ nommée Ratio permettant de traiter des nombres rationnels quelconques sans passer par des float ou des double qui nous obligeraient à commettre des erreurs d'arrondi.

En partant de ce qui a été vu en cours, compléter la classe Ratio en fonction du cahier des charges suivant. Toutes les fonctionnalités demandées doivent être réalisées, et leur bon fonctionnement vérifié.

La classe Ratio code un nombre rationnel de la forme n/d en stockant indépendamment son numérateur (n) et son dénominateur (d) qui sont tous les deux des entiers. Le numérateur servira à coder le signe du rationnel. Le dénominateur devra donc toujours rester positif. L'accès aux membres numérateur et dénominateur ne doit pas être permis autrement que par des fonctions accesseurs. Deux types d'accesseurs existeront : des accesseurs permettant d'extraire la valeur du numérateur (ou du dénominateur), et des accesseurs permettant la modification des membres.

Une méthode reduire() doit être intégrée à la classe. Elle permet de réduire la fraction : c'est-à-dire de trouver la fraction équivalente ayant les numérateurs et dénominateurs les plus petits possibles en valeur absolue. On rappelle que pour réduire la fraction, il faut diviser le numérateur et le dénominateur par leurs le PGCD. Par exemple, la fraction 45/30 n'est pas réduite car 45 = 5×3×3 et 30=5×3×2, on peut donc diviser le numérateur et le dénominateur par le PGCD(45,30)=15, et ainsi obtenir la fraction réduite 3/2.

La modification par un des accesseurs de modification doit déclencher systématiquement une simplification de la fraction, ainsi la fraction sera toujours réduite.

Il doit être possible de définir une instance de Ratio en précisant la valeur du numérateur et du dénominateur. Il doit également être possible de créer un rationnel à partir d'un nombre entier relatif quelconque ; on posera alors que le dénominateur vaut 1. Enfin, on doit pouvoir créer un rationnel nul  lorsqu'on défini un Ratio sans préciser la valeur de son numérateur et de son dénominateur.

Comme pour toute classe que vous écrirez, vous devez définir le constructeur de copie pour un Ratio.

L'écriture d'un rationnel sur un flux (avec <<) doit produire une sortie de la forme "3/2" si le dénominateur est différent de 1, de la forme "10" lorsque le dénominateur est égal à 1 et qu'il s'agit donc d'un entier relatif.

La lecture sur un flux (avec >>) doit aussi lire un rationnel de la forme "-45/-12" aussi bien que "-23". La lecture, comme la modification par les accesseurs, devra provoquer une réduction de la fraction.

Il doit être possible d'affecter une instance de Ratio à une autre.

Il doit être possible de calculer une valeur approchée du rationnel avec une méthode double valeur().

Il doit être possible d'inverser un rationnel (attention, il y a un petit piège à éviter avec le signe du rationnel).

Il soit être possible d'additionner deux Ratio, un Ratio et un entier relatif... ainsi que l'inverse, c'est-à-dire additionner un entier relatif avec un Ratio.

Sur le même principe, toutes les opérations possibles autour de la soustraction, de la multiplication et de la division doivent être réalisées.

Il doit également être possible d'utiliser les opérateurs de pré- et post-incrémentation, de pré- et post-décrémentation, ainsi que les opérateurs +=, -=, *=, et /=.

Remarques pour ceux qui pensent avoir fini ce TP :

Si oui, tentez de répondre à la question subsidiaire...

Question subsidiaire :

Coder une méthode void Ratio::convert(double valeur, double precision) pour trouver un rationnel approchant valeur avec une erreur au plus égale à precision. On se servira pour ce calcul d'une approximation par des fractions continues (dont vous pouvez trouver une définition sur Wikipedia en anglais pour l'instant. Regardez en particulier la manière dont est obtenue un approximation de pi avec la fraction 355/113).

Ajouter le constructeur, permettant de créer un rationnel approchant un réel à une précision donnée.