• Aucun résultat trouvé

3 Les limites de l'approche descendante

1. Une calculatrice pour le grand Jules

1.6 Analyse de DECIMALISER .1 DECIMALISER ? Quoi faire ?

1.7.3 ROMANISER. Comment faire faire ?

On pourrait d'abord écrire en utilisant les deux variables RomainPlusGrandQue1000 et

RomainPlusPetitQue1000, toutes deux de type NombreRomain :

Si Decimal ≥ 4000 alors

ROMANISER_MORCEAU_SUPERIEUR_A_1000 RomainPlusGrandQue1000 de type NombreRomain

ROMANISER_MORCEAU_INFERIEUR_A_1000 RomainPlusPetitQue1000 de type NombreRomain Romain RomainPlusGrandQue1000 + RomainPluspetitQue1000 (1)

sinon

ROMANISER_DECIMAL

(1) Le signe + dénote ici la concaténation (= le fait de les coller l'une à l'autre) des deux chaînes de caractères RomainPlusGrandQue1000 et RomainPluspetitQue1000. La première de ces variables RomainPlusGrandQue1000 sert à contenir l'équivalent en chiffres romains du nombre de milliers de Decimal; la seconde RomainPluspetitQue1000 sert à contenir l'équivalent en chiffres romains de la partie de Decimal inférieure à 1000.

Pour mieux saisir ce que représentent les deux variables RomainPlusGrandQue1000 et

RomainPluspetitQue1000, il reste comme d'habitude à préciser les actions complexes apparues :

ROMANISER_MORCEAU_SUPERIEUR_A_1000

Decimal

de type entier long

Transformer la partie multipliant 1000 de Decimal (le nombre de milliers de Decimal) en un nombre en chiffres romains, dont tous les symboles sont assortis

de ° et placer ce résultat dans

RomainPlusGrandQue1000

RomainPlusGrandQue1000 de type NombreRomain

avec

Avant Après

- Decimal de type entier long, contenant un entier entre 4000 et 998001

- RomainPlusGrandQue1000, de type NombreRomain contenant l'équivalent en chiffres romains assortis du symbole ° de la partie de Decimal multiple de 1000.

et

ROMANISER_MORCEAU_INFERIEUR_A_1000

Decimal

de type entier long

Transformer la partie inférieure à 1000 de Decimal en un nombre en chiffres romains et placer ce résultat dans

RomainPlusPetitQue1000

RomainPlusPetitQue1000 de type NombreRomain avec

Avant Après

- Decimal de type entier long, contenant un entier entre 4000 et 998001

- RomainPlusPetitQue1000, de type NombreRomain contenant l'équivalent en chiffres romains de la partie de Decimal strictement inférieure à 1000.

On notera que pour chacune de ces actions, le paramètre Decimal contient un nombre supérieur à 4000, étant donné l'analyse de ROMANISER telle que conduite ci-dessus.

Et enfin :

ROMANISER_DECIMAL

Decimal

de type entier long

Transformer Decimal en un nombre en chiffres romains

et placer ce résultat dans Romain Romain

de type NombreRomain avec

Avant Après

- Decimal de type entier long, contenant un entier entre 0 et

3999

- Romain, de type NombreRomain contenant l'équivalent en chiffres romains de Decimal.

Une fois de plus, on peut unifier en une action unique ces diverses actions, même si l'écriture du symbole ° pour la partie de Decimal multiple de 1000 complique un peu la tâche.

Plutôt que de passer Decimal à ROMANISER_MORCEAU_SUPERIEUR_A_1000 en confiant à cette procédure le fait d'extraire la partie multipliant 1000 de Decimal et de la "romaniser" et de passer la même valeur Decimal à ROMANISER_MORCEAU_ INFERIEUR_A_1000 en demandant à cette procédure d'extraire la partie inférieure à 1000 et la "romaniser", nous allons en tout cas, lorsque Decimal est supérieur à 4000, commencer par isoler la partie de Decimal multiple de 1000, puis la partie inférieure à 1000 avant d'appeler à deux reprises une procédure unique de "romanisation" de ces deux "morceaux".

Il est facile de voir que cette action, que nous allons baptiser ROMANISER_TOUT_OU_PARTIE, doit en tout cas être assortie d'un paramètre "d'entrée" dans lequel nous passerons d'abord Decimal div 1000 (partie de Decimal multipliant 1000), puis Decimal mod 1000 (partie de Decimal inférieure à 1000) ou encore Decimal lui-même. Il nous faut aussi un paramètre de "sortie", baptisé Romain, qui sera, dans le premier cas un "prête-nom" pour

NombreRomainPlusGrandQue1000, dans le second cas un "prête-nom" pour NombreRomainPlusPetitQue1000, et enfin dans le troisième cas un "prête-nom" pour Romain

lui-même.

Il nous faut cependant un paramètre d'entrée supplémentaire qui signale si oui ou non la procédure ROMANISER_TOUT_OU_PARTIE reçoit la partie de Decimal multiple de 1000 (auquel cas il faut adjoindre aux caractères composant le nombre en chiffres romains obtenu, le symbole °).

Ainsi donc, l'action ROMANISER_TOUT_OU_PARTIE sera accompagnée de 2 paramètres d'entrée :

- Habituel, de type entier long, qui recevra le nombre décimal à transformer en nombre romain

- AuDelaDe1000, booléen, vrai lorsque le nombre passé dans Habituel constitue la partie

multiple de 1000 de Decimal et que dès lors les caractères du résultat doivent être accompagnés de °.

En effet, en l'absence d'un paramètre AuDelaDe1000 signalant s'il s'agit de transformer en chiffres romains la partie de Decimal multipliant 1000 ou la partie inférieure à 1000 ou encore

Decimal lui-même, la procédure ROMANISER_TOUT_OU_PARTIE ne "connaîtrait" et ne

travaillerait que sur la valeur donnée au paramètre Habituel sans "savoir" si la "romanisation" doit ou non accompagner les caractères romains du symbole °. Le simple fait de garnir le paramètre Habituel avec la valeur Decimal div 1000, avec Decimal mod 1000 ou avec Decimal, ne suffit pas pour que ROMANISER_TOUT_OU_PARTIE "sache" dans quel cas on se trouve. Ainsi ROMANISER_TOUT_OU_PARTIE recevant 68 comme valeur de Habituel ne peut savoir si 68 est la partie du nombre à transformer multipliant 1000 (auquel cas le symbole ° doit être adjoint aux chiffres romains) ou la partie inférieure à 1000 (auquel cas le symbole ° est inutile). Il faut donc un paramètre supplémentaire AuDelaDe1000 sur base duquel décider si ° doit ou non être adjoint.

Tout cela apparaîtra plus nettement encore lorsque je détaillerai (page 148) la manière dont s'effectuera le dialogue au moment d'un appel de procédure assortie de paramètres.

Il faut également un paramètre de sortie :

- Romain de type NombreRomain comportant l'équivalent en chiffres romains du nombre reçu

dans Habituel.

En résumé, nous avons donc :

ROMANISER_TOUT_OU_PARTIE(Habituel : entier long;

AuDelaDe1000 : booléen; var Romain : NombreRomain) Habituel

de type entier long

AuDelaDe1000 de type booléen

Transformer le nombre entier Habituel en son équivalent romain en plaçant à côté de chaque chiffre romain le

symbole ° lorsque AuDelaDe1000 est vrai et sans symbole ° dans le cas contraire. Dans tous les cas le

résultat obtenu doit être placé dans Romain.

Romain

de type NombreRomain

avec

Avant Après

- Habituel de type entier long contenant le nombre décimal à transformer; toujours compris entre 0 et 3999.

- AuDelaDe1000 , de type booléen, vrai lorsque les caractères du nombre romain à construire doivent être accompagnés de °.

- Romain , de type NombreRomain contenant l'équivalent en chiffres romains (accompagnés ou non de °) du contenu de

Habituel.

Avec cette description de l'action de "romanisation", on peut réécrire la marche à suivre correspondant à ROMANISER :

Si Décimal ≥ 4000 alors

ROMANISER_TOUT_OU_PARTIE (Decimal div 1000, vrai, RomainPlusGrandQue1000)

RomainPlusGrandQue1000 de type NombreRomain

ROMANISER_TOUT_OU_PARTIE (Decimal mod 1000, faux, RomainPlusPetitQue1000)

RomainPlusPetitQue1000 de type NombreRomain Romain RomainPlusGrandQue1000 + RomainPluspetitQue1000

sinon

Il faut une fois de plus mettre en parallèle la définition des paramètres de ROMANISER_TOUT_OU_PARTIE et ce qui leur est associé lors de chaque appel :

Définition: ROMANISER_TOUT_OU_PARTIE( Habituel; AuDelaDe1000; Romain)

1er appel: ROMANISER_TOUT_OU_PARTIE(Decimal div 1000, vrai, RomainPlusGrandQue1000)

Définition: ROMANISER_TOUT_OU_PARTIE( Habituel; AuDelaDe1000; Romain)

2è appel: ROMANISER_TOUT_OU_PARTIE(Decimal mod 1000, faux, RomainPlusPetitQue1000)

Définition: ROMANISER_TOUT_OU_PARTIE( Habituel; AuDelaDe1000; Romain)

3è appel : ROMANISER_TOUT_OU_PARTIE( Decimal, faux, Romain)

Autrement dit, au lieu de

- ROMANISER_MORCEAU_SUPERIEUR_A_1000, on appellera ROMANISER_TOUT_ OU_PARTIE en précisant que

- Habituel vaut Decimal div 1000

- AuDelaDe1000 est vrai

- Romain est RomainPlusGrandQue1000

au lieu de

- ROMANISER_MORCEAU_INFERIEUR_A_1000, on appellera ROMANISER_TOUT_ OU_PARTIE en précisant que

- Habituel vaut Decimal mod 1000

- AuDelaDe1000 est faux

- Romain est RomainPlusPetitQue1000

et enfin, au lieu de

- ROMANISER_DECIMAL, on appellera ROMANISER_TOUT_OU_PARTIE en précisant que

- Habituel vaut Decimal

- AuDelaDe1000 est faux

- Romain est Romain

Nous sommes dès lors, à ce stade, en mesure de répondre à