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 :
- Avez-vous mis des const
à tous les endroits où leur présence serait
justifiée ?
- Avez-vous pris garde à ce que tout Ratio en
mémoire soit toujours sous forme réduite ?
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.