You are on page 1of 15

Centre Informatique pour les Lettres

et les Sciences Humaines


C++ - TD 17
Entiers de Taille Inhabituelle
1 - Rflexions pralables............................................................................................................... 2
2 - Interface et classe de dialogue................................................................................................. 2
- !a classe "TI et ses #ariables $e$bre.....................................................................................
% - Cration et destruction d&"ntiers de Taille Inhabituelle............................................................
!a construction par dfaut et la fonction base'lloc()............................................................
!a construction par copie et la fonction nb*ctets+tils()........................................................%
Transt,page - partir d&une s.uence de chiffres................................................................... /
Transt,page - partir d&un int............................................................................................... /
!a fonction stati.ue hasard() et la fonction redi$()............................................................... 0
Destruction......................................................................................................................... 0
/ - 'ffectation d&une #aleur - un "ntier de Taille Inhabituelle....................................................... 7
0 - Co$paraisons entre "ntiers de Taille Inhabituelle................................................................... 7
!es tests d&galit et de diffrence........................................................................................ 7
!es tests d&infriorits et la fonction abs()............................................................................. 1
!es tests de supriorit........................................................................................................ 2
7 - 'dditions d&"ntiers de Taille Inhabituelle................................................................................. 2
!&addition sans effet et la fonction a3oute()........................................................................... 2
!es additions - effet........................................................................................................... 14
1 - 5oustractions d&"ntiers de Taille Inhabituelle........................................................................ 14
!a soustraction sans effet et la fonction enle#e()................................................................. 14
!es soustractions - effet.................................................................................................... 11
2 - 6ultiplications d&"ntiers de Taille Inhabituelle...................................................................... 11
!a $ultiplication sans effet et la fonction foisDeux()........................................................... 11
!a $ultiplication - effet..................................................................................................... 12
14 - Di#isions d&"ntiers de Taille Inhabituelle............................................................................. 1
!es di#isions sans et a#ec effet et l&oprateur 7.................................................................. 1
!a fonction di#ise()............................................................................................................. 1
11 - Reprsentation textuelle d&un "ntier de Taille Inhabituelle................................................... 1%
12 - !e fichier eti.h..................................................................................................................... 1/
Docu$ent du 27841840 - Retrou#e9 la #ersion la plus rcente sur http:88;;;.up.uni#-$rs.fr8;cpp
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 2 8 1/
!e progra$$e .ue nous allons raliser au cours de ce TD tire deux no$bres entiers au hasard et
les affiche> ainsi .ue leur produit :
5i ce rsultat $an.ue #ide$$ent d&intr?t> la $ise au point du progra$$e #a nous conduire -
dfinir une classe ETI> capable de grer des #aleurs enti@res large$ent suprieures - celles
$anipulables - l&aide des t,pes prdfinis int ou long int. Cette classe est un exe$ple
d&encapsulation de l&allocation d,na$i.ue et peut ?tre utilise dans d&autres pro3ets. Aote9>
toutefois> .u&il s&agit d&un si$ple exercice et .ue le code propos ici ne prtend offrir ni la fiabilit
ni l&efficacit des librairies (telles .ue la BA+ 6ultiple Crecision 'rith$etic !ibrar,> par exe$ple)
destines - ?tre utilises dans de #ritables applications.
!&absence de prtentions de la classe ETI est souligne par son no$> clin d&oeil aux RTI
(Rongeurs de Taille Inhabituelle) du fil$ DThe Crincess ErideD.
1 - Rflexions pralables
!a reprsentation d&une #aleur enti@re exige une .uantit de $$oire .ui dpend de la taille de
cette #aleur. Dans le cas des t,pes prdfinis> la taille est fixes arbitraire$ent et tous les ob3ets
du $?$e t,pe ont la $?$e taille. !a reprsentation d&une petite #aleur laisse donc un certain
no$bre de bits inutiliss> et la taille choisie i$pose une li$ite aux #aleurs .ui peu#ent ?tre
reprsentes (% 22% 207 22/ pour un entier non sign reprsent sur % octets> par exe$ple).
Cour un t,pe #isant - per$ettre de $anipuler de tr@s grands no$bres> cette approche n&est pas
tr@s pro$etteuse : une taille fixe conduit - la fois - accepter une li$ite (.ui ris.ue de s&a#rer tFt
ou tard trop basse) et - $obiliser beaucoup de $$oire sans l&utiliser relle$ent lors.ue les
#aleurs reprsentes sont tr@s infrieures - cette li$ite.
!a classe "TI adopte donc un fonctionne$ent plus proche de celui des QString .ue de celui des
int : la place utilise pour reprsenter une #aleur est #ariable et s&a3uste auto$ati.ue$ent en
fonction des besoins.
2 - Interface et classe de dialogue
+tilise9 la procdure habituelle (cf. aide $$oire) pour crer un pro3et no$$ TD17 et efface9
tous les ;idgets prsents dans le dialogue .
Clace9 sur le dialogue un QTextEdit (6enu Tools> catgorie Displa,) no$$ ecran .
A&oublie9 pas d&enregistrer #otre tra#ail a#ant de re#enir - <isual C++ .
!e code ncessaire est tr@s bref et> co$$e nous souhaitons si$ple$ent .u&il s&excute lors.ue le
progra$$e est lanc> nous le plaGons directe$ent dans le constructeur du dialogue :
TD17DialogImpl::TD17DialogImpl(QWidget* parent, const char* name, bool modal, Wlags ! "
: TD17Dialog( parent, name, modal, ! "
#
srand(time($""%
ETI a & ETI::hasard('("%
ETI b & ETI::hasard()("%
ETI prod*it & a * b%
ecran+,setText(a-texte(" . /0n!ois0n/ . b-texte(" . /0n&0n/ . prod*it-texte(""%
1
Re$ar.ue9 .ue :
- !es #ariables a et b sont initialises a#ec des #aleurs alatoires ren#o,es par une fonction
stati.ue dont le para$@tre indi.ue le no$bre d&octets .ue cette #aleur peut occuper en $$oire.
Il faut donc .ue la classe ETI fournisse un constructeur par copie et une fonction hasard(".
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 8 1/
- !a #ariable prod*it est initialise a#ec une #aleur de t,pe ETI obtenue en $ultipliant a par b. Il
faut donc .ue la classe ETI fournisse un oprateur de $ultiplication.
- !es trois instances de ETI sont utilises pour appeler une fonction .ui ren#oie la s.uence de
chiffres .ui reprsente leur #aleur dans la notation positionnelle en base 14 utilisant les chiffres
arabes.
Donne9 - #otre constructeur de dialogue le contenu suggr ci-dessus .
- !a classe ETI et ses #ariables $e$bre
'3oute9 - #otre pro3et une classe no$$e ETI et ne dri#ant d&aucune autre .
!a gestion d&une 9one de $$oire de taille #ariable pour reprsenter la #aleur de l&ob3et i$pose
l&utilisation de deux #ariables $e$bre : l&une de#ra stocHer la taille de la 9one> l&autre son adresse.
!a pre$i@re de ces #ariables> no$$es m2taille> est de t,pe unsigned int.
D&un point de #ue pure$ent thori.ue> adopter un t,pe prdfini pour cette #ariable re#ient -
fixer une li$ite aux #aleurs reprsentables par la classe ETI. Crati.ue$ent> toutefois> aucun
ordinateur actuel ne pourrait faire .uoi .ue ce soit a#ec une .uantit enti@re dont la
reprsentation occuperait % 22% 207 22/ octets...
!&adresse de la 9one oI est reprsente la #aleur doit #ide$$ent ?tre stocHe dans un pointeur>
$ais de .uel t,pe J !ors.ue> co$$e c&est le cas ici> nous #oulons .ue le langage consid@re les
donnes co$$e de si$ples tats lectri.ues et laisse au progra$$e l&enti@re responsabilit de
leur donner une interprtation> le plus si$ple est de considrer .ue les donnes sont une
collection de #aleurs de t,pe *nsigned char.
Il n&existe pas de t,pe b3te (octet) en C++> et les progra$$eurs ont depuis longte$ps pris
l&habitude d&utiliser des *nsigned char - la place. !e seul rel incon#nient de cette faGon de
procder est la connotation textuelle .u&a le $ot char pour la plupart des dbutants.
5i nous souhaitons pou#oir $anipuler des .uantits ngati#es> il nous faut gale$ent $ettre en
place un s,st@$e de $$orisation du signe. +ne approche si$ple est d&introduire une #ariable
$e$bre de t,pe boolen> .ui indi.uera si le no$bre est positif.
!es t,pes prdfinis ne proc@dent habituelle$ent pas - un stocHage spar du signe et de la
#aleur absolue. !a techni.ue .u&ils utilisent (cf. !eGon 1) ne prsente toutefois gu@re d&intr?t
dans le cas de #aleurs .ui ne sont pas toutes reprsentes sur le $?$e no$bre d&octets.
'3oute9 - #otre classe ETI les trois #ariables $e$bre sui#antes :
*nsigned int m2taille%
*nsigned char * m24ale*r%
bool m2positi!%
% - Cration et destruction d&"ntiers de Taille Inhabituelle
6?$e si l&tat actuel du progra$$e ne l&exige pas explicite$ent> il est #ident .u&un constructeur
par dfaut est prati.ue$ent indispensable - la classe ETI (ne serait-ce .ue pour nous per$ettre
de ranger des #aleurs de ce t,pe dans une Q5ap ou une Q6al*e7ist). Il est gale$ent
#raise$blable .ue la plupart des utilisations de la classe ETI i$pli.ueront des #ariables
initialises a#ec des #aleurs non alatoires. Deux $thodes d&initialisation se$blent
particuli@re$ent attra,antes : - partir d&un entier (lors.ue la #aleur le per$et) et - partir d&une
chaKne de chiffres dcri#ant la #aleur (lors.ue celle-ci exc@de les possibilits des t,pes prdfinis).
Deux constructeur de transt,page nous per$ettront d&crire des choses co$$e :
ETI *ne6ale*r & 1% 88transt3page 9 partir d:*n int
ETI *ne;*tre & /<<< <<< <<< <<</% 88transt3page 9 partir d:*ne cha=ne
!a construction par dfaut et la fonction base;lloc("
!a construction par dfaut produit une instance nulle en $ettant - 9ro (4-6) tous les octets de la
9one consacre - la reprsentation de la #aleur. Cette 9one est rser#e en faisant appel - une
fonction de ser#ice (.ui sera gale$ent utilise par d&autres constructeurs ou fonctions $e$bre).
J-L Pris - 27/01/06
1
2
3
1
2
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle % 8 1/
ETI::ETI(" : m2positi!(tr*e", m2taille($", m24ale*r(>?77"
#
base;lloc("%
*nsigned int p%
!or(p & $ % p @ m2taille % ..p"
m24ale*rApB & $%
1
!a fonction base;lloc(" proc@de - une allocation d,na$i.ue (3) entoure des prcautions
habituelles (4-). 5i cette opration russit> elle stocHe dans m2taille le no$bre d&octets
disponibles dans la 9one de donnes :
4oid ETI::base;lloc(*nsigned int t"
#
m24ale*r & neC *nsigned charAtB%
i!(m24ale*r && $"
#
Q5essageDox::critical($, /Elasse ETI/, /5Fmoire ins*!!isante/"%
G;pp+,exit(+1"% 88met br*talement !in 9 l:exFc*tion d* programme
ret*rn%
1
m2taille & t%
1
!a construction par copie et la fonction nbHctets?tils("
!a construction par copie ne se distingue de la construction par dfaut .ue par le fait .ue la 9one
de donnes reGoit une copie de la 9one de donnes du $od@le (!-7). Il faut donc .ue l&instance en
cours de construction dispose d&une 9one d&une taille adapte> et cette taille est obtenue en
in#o.uant une fonction pr#ue - cet effet.
!e constructeur par copie se contente d&une 9one .ui#alente - l&espace effecti#e$ent occup
par la #aleur contenue dans le $od@le au $o$ent de la copie. Il aurait aussi t possible
d&allouer une 9one de la $?$e taille .ue celle utilise par le $od@le.
ETI::ETI(const ETI I modele": m2positi!(modele-m2positi!", m2taille($",
m24ale*r(>?77"
#
const *nsigned int T;I77E & modele-nbHctets?tils("%
base;lloc(T;I77E"%
*nsigned int p%
!or(p & $ % p @ T;I77E % ..p"
m24ale*rApB & modele-m24ale*rApB%
1
Il est aussi prati.ue de disposer d&un constructeur par Dcopie partielleD> .ui adopte la #aleur
absolue du $od@le> $ais per$et de spcifier le signe de l&instance construite :
ETI::ETI(const ETI I 4ale*r, bool signe": m2positi!(signe", m2taille($",
m24ale*r(>?77"
#
const *nsigned int T;I77E & 4ale*r-nbHctets?tils("%
base;lloc(T;I77E"%
*nsigned int p%
!or(p & $ % p @ T;I77E % ..p"
m24ale*rApB & 4ale*r-m24ale*rApB%
1
!a fonction nbHctets?tils(" parcourt la 9one de donnes> en co$$enGant par la fin> 3us.u&- ce
.uelle rencontre un octet non-nul.
!es octets nuls en fin de 9one de donnes n&a3outent rien - la #aleur reprsente> exacte$ent
co$$e les 9ros de gauche dans le $ontant d&un ch@.ue : 444414 L MM 14 L.
J-L Pris - 27/01/06
1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
1
1
2
3
4
5
6
7
8
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle / 8 1/
*nsigned int ETI::nbHctets?tils(" const
#
*nsigned int p & m2taille+1% 88m24ale*rApB est le dernier octet de la Jone de donnFes
Chile(p ,& $ II m24ale*rApB && $"
++p% 88on rec*le K*sG*:a* premier octet non n*l
ret*rn p.1%
1
Transt,page - partir d&une s.uence de chiffres
!a construction d&une #aleur nu$ri.ue - partir d&une s.uence de chiffres reprend la logi.ue
utilise pour la ralisation de la calculette du TD : les chiffres sont lus de la gauche #ers la
droite et la prise en co$pte d&un nou#eau chiffre a donc pour effet de $ultiplier la #aleur actuelle
par 14 a#ant de lui a3outer la #aleur correspondant au nou#eau chiffre.
ETI::ETI(const char * s"
#
m2positi! & (sA$B L& :+:"%
ETI la6ale*r;bsol*e%
int p & (m2positi! M $ : 1"% 88sa*te le :+: initial F4ent*el
Chile(sApB ,& :$: II sApB @& :<:"
#
la6ale*r;bsol*e *& 1$%
la6ale*r;bsol*e .& sApB N :$:% 88:7: N :$: donne 7, par exemple
Chile(sA..pB && : :"% 88ignore les espaces intercalFs entre les chi!!res
1
m2taille & la6ale*r;bsol*e-m2taille%
m24ale*r & la6ale*r;bsol*e-m24ale*r%
la6ale*r;bsol*e-m24ale*r & >?77% 88la6ale*r;bsol*e 4a Otre dFtr*ite L
1
!a 4ale*r;bsol*e est calcule dans un ETI local dont l&instance en construction #a conser#er la
9one de donnes (13). Co$$e le destructeur de ETI #a ?tre excut au titre de cette instance locale
d@s la fin de l&excution de la fonction> il faut #eiller a e$p?cher (14) ce destructeur de librer la
9one en .uestion (appli.uer l&oprateur deleteNO - un pointeur >?77 est sans effet ni danger).
Transt,page - partir d&un int
Cour construire un ETI - partir d&un int> il faut $$oriser le signe du $od@le et reprsenter sa
#aleur absolue dans une 9one de donne (6-11) d&une taille suffisante (!).
ETI::ETI(int 4" : m2positi!(4 ,& $"
#
i!(4 @ $"
4 & +4%
base;lloc(siJeo!(int""%
*nsigned int p&$%
!or(p & $ % p @ m2taille % ..p"
#
m24ale*rApB & 4 P '(Q%
4 8& '(Q%
1
1
!es octets .ui reprsentent la #aleur sont calculs (-10) plutFt .ue lus directe$ent dans la
#ariable 4> pour #iter de faire des h,poth@ses hasardeuses sur la faGon dont sont reprsents
les int (octet de poids faible en t?te ou en .ueue J). Ce calcul est facile$ent co$prhensible si
l&on consid@re .ue la s.uence d&octets recherche correspond - une reprsentation de la #aleur
en base 2/0> les chiffres utiliss tant les 2/0 #aleurs possibles pour un octet.
J-L Pris - 27/01/06
1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 0 8 1/
!a fonction stati.ue hasard(" et la fonction redim("
Eien .u&il ne s&agisse pas d&un constructeur> hasard(" est nan$oins une fonction dont
l&in#ocation gn@re une #aleur de t,pe ETI> et son usage se rapprochera donc de celui d&un
constructeur. "lle doit ren#o,er une instance de la classe ETI de la taille spcifie par son
para$@tre> et elle se procure un tel ob3et en redi$ensionnant> - l&aide d&une fonction de ser#ice>
une instance issue d&une construction par dfaut. !a #aleur DalatoireD est obtenue en tirant au
hasard chacun des octets de la 9one de donnes (!-7)> ainsi .ue le signe (").
ETI ETI::hasard(*nsigned long taille"
#
ETI tirage%
tirage-redim(taille, !alse"%
*nsigned int p%
!or (p & $ % p @ taille % ..p"
tirage-m24ale*rApB & rand(" P '(Q%
tirage-m2positi! & rand(" P '%
ret*rn tirage%
1
!a fonction redim(" dispose de deux para$@tres : le pre$ier spcifie la nou#elle taille souhaite>
et le second indi.ue si l&ancienne #aleur doit ?tre conser#e. !ors.ue c&est le cas> il est
#ide$$ent i$possible d&adopter une taille infrieure au no$bre d&octets ncessaires pour
reprsenter l&ancienne #aleur (3-4). +ne fois .u&une 9one d&une taille ad.uate a t cre et
initialise correcte$ent> l&ancienne 9one de donnes est restitue au s,st@$e (1") et la nou#elle est
adopte (1-20) par l&instance Dredi$ensionneD :
4oid ETI::redim(*nsigned int no*4elleTaille, bool conser4er6ale*r"
#
i!(conser4er6ale*r II (nbHctets?tils(" , no*4elleTaille" "
ret*rn%
88crFation de la no*4elle Jone de donnFes
*nsigned char * no*4elleRone & neC *nsigned charAno*4elleTailleB%
i!(no*4elleRone && $"
#
Q5essageDox::critical($, /Elasse ETI/, /5Fmoire ins*!!isante/"%
G;pp+,exit(+1"% 88met br*talement !in 9 l:exFc*tion d* programme
ret*rn%
1
88initialisation de la no*4elle Jone de donnFes
*nsigned int p%
!or(p & $ % p @ no*4elleTaille % ..p"
i! (conser4er6ale*r II p @ m2taille"
no*4elleRoneApB & m24ale*rApB%88copie l:ancienne 4ale*r dans la no*4elle Jone
else
no*4elleRoneApB & $%
88adoption de la no*4elle Jone de donnFes
deleteAB m24ale*r%
m24ale*r & no*4elleRone%
m2taille & no*4elleTaille%
1
Destruction
Co$$e nous l&a#ons #u dans la !eGon 17> le rFle fonda$ental du destructeur d&une classe
encapsulant l&allocation d,na$i.ue est la restitution de la $$oire alloue :
ETI::SETI("
#
deleteAB m24ale*r%
P
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 7 8 1/
/ - 'ffectation d&une #aleur - un "ntier de Taille Inhabituelle
Co$$e sou#ent> l&oprateur d&affectation resse$ble beaucoup - un constructeur par copie. !a
seule diffrence est .u&il existe d3- une 9one de donnes attribue - l&instance .ui doit prendre
une nou#elle #aleur. !ors.ue la taille de cette 9one ne suffit pas pour accueillir la #aleur affecte>
il faut l&a3uster (4-!). Cet exercice co$porte un pi@ge : si le $?$e ob3et figure des deux cFts de
l&oprateur d&affection> la restitution de l&ancienne 9one de donnes effectue par redim(" rend
in#alide le pointeur utilis ensuite pour accder - la Dnou#elleD #aleur. Dans le cas prsent> l&auto-
affectation ne pose pas de probl@$e> puis.u&il est inconce#able .ue l&ob3et concern dispose d&un
espace insuffisant pour stocHer... la #aleur .u&il contient d3- Q
!&auto-affectation est un phno$@ne bien plus fr.uent .u&on pourrait le croire. Aon pas parce
.ue certains progra$$eurs se plaisent - crire des chose du genre
*ne6ariable & *ne6ariable% 88MMMMMM
$ais parce .ue les ob3ets ne sont pas tou3ours dsigns par leur no$> et .u&il n&est pas
i$possible .ue> par exe$ple> deux pointeurs (ou deux rfrences) dsignent le $?$e ob3et.
ETI I ETI::operator &(const ETI I a*tre"
#
const int T;I77E2EHTIE & a*tre-nbHctets?tils("%
i!(m2taille @ T;I77E2EHTIE"
redim(T;I77E2EHTIE, !alse"% 88serait dFsastre*x en cas d:a*to+a!!ectation L
m2positi! & a*tre-m2positi!%
*nsigned int p%
!or (p & $ % p @ m2taille % ..p"
m24ale*rApB & (p @ T;I77E2EHTIE" M a*tre-m24ale*rApB : $%
ret*rn * this%
1
Re$ar.ue9 .ue> du fait de la disponibilit de constructeurs de transt,page> l&oprateur
d&affectation .ue nous #enons d&crire suffit - autoriser des choses co$$e :
ETI *nUrand>ombre% 88initialisF 9 $ par dF!a*t
*nUrand>ombre & 1% 88constr*ction 9 partir d:int et a!!ectation
*nUrand>ombre & /< V7Q (W) '1$/% 88constr*ction 9 partir de char * et a!!ectation
0 - Co$paraisons entre "ntiers de Taille Inhabituelle
!es oprateurs de co$paraison sont tr@s facile - progra$$er et seront #raise$blable$ent
indispensables - tout progra$$e $anipulant des ETI.
!es tests d&galit et de diffrence
bool ETI::operator && (const ETI I a*tre" const
#
const *nsigned int T;I77E & nbHctets?tils("%
const *nsigned int ;?TXE2T;I77E & a*tre-nbHctets?tils("%
i!(T;I77E && $ II ;?TXE2T;I77E && $"
ret*rn tr*e%
i!(m2positi! L& a*tre-m2positi! YY T;I77E L& ;?TXE2T;I77E"
ret*rn !alse%
*nsigned int position%
!or (position & $ % position @ T;I77E % ..position"
i!(m24ale*rApositionB L& a*tre-m24ale*rApositionB"
ret*rn !alse%
ret*rn tr*e%
1
Deux #aleurs sont gales si elles sont nulles (!-6)> $ais ne peu#ent ?tre gales si leurs signes
diff@rent> si leurs reprsentations n&exigent pas la $?$e .uantit de $$oire (7-8) ou si ces
reprsentations ne co$portent pas des octets identi.ues - toutes les positions (-13).
Deux #aleurs sont diffrentes si... elles ne sont pas gales :
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
9
10
11
1
2
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 1 8 1/
bool ETI::operator L& (const ETI I a*tre" const
#
ret*rn L (*this && a*tre"%
1
!es tests d&infriorits et la fonction abs("
!ors.ue les deux #aleurs ne sont pas de $?$e signe> leur co$paraison est i$$diate car elle
n&i$pli.ue pas les #aleurs absolues (3-6). 5i les deux no$bres sont ngatifs> ils s&ordonnent -
l&in#erse de leurs #aleurs absolues (7-"). !e seul cas - exa$iner en dtail est donc celui ou les deux
#aleurs sont positi#es (-23). 5i les reprsentations sont de tailles diffrentes> celle .ui exige le plus
d&octets est #ide$$ent celle .ui correspond au no$bre le plus grand (-12). 5i les deux
reprsentations sont de la $?$e taille> il faut les co$parer en co$$enGant (13-14) par l&octet de
poids $axi$u$ (244 est suprieur - 122> par exe$ple) : d@s .u&une di#ergence apparaKt> l&ordre
des octets concerns donne l&ordre des #aleurs :
bool ETI::operator @ (const ETI I a*tre" const
#
i!(m2positi! II La*tre-m2positi!"
ret*rn !alse% 88*n positi! est s*pFrie*r 9 *n nFgati!
i!(L m2positi! II a*tre-m2positi!"
ret*rn tr*e% 88*n nFgati! est in!Frie*r 9 *n positi!
i! (Lm2positi! II La*tre-m2positi!"
ret*rn L (abs(" @ a*tre-abs(""% 88ordre in4erse des 4ale*rs absol*es
88ils sont to*s de*x positi!s
*nsigned int n1 & nbHctets?tils("%
*nsigned int n' & a*tre-nbHctets?tils("%
i! (n1 L& n'"
ret*rn n1 @ n'% 88le pl*s co*rt est pl*s petit
88ils occ*pent le mOme nombre d:octets en mFmoire
*nsigned char * ptr & m24ale*r . n1 + 1%
88ptr pointe s*r le dernier octet signi!icati! de m24ale*r
*nsigned char * a*treTtr & a*tre-m24ale*r . n' + 1%
88a*treTtr pointe s*r le dernier octet signi!icati! de a*tre-m24ale*r
Chile (ptr ,& m24ale*r"
#
i!(*ptr L& *a*treTtr"
ret*rn *ptr @ *a*treTtr%
++ptr%
++a*treTtr%
1
ret*rn !alse% 88ils sont Fga*x L
1
Re$ar.ue9 .ue le parcours des 9ones de donnes (1!-21) est effectu en $anipulant
explicite$ent deux pointeurs et non - l&aide d&un index entre crochets. Co$$e nous feignons de
croire .ue la taille de ces 9ones doit ?tre stocH dans un *nsigned int> nous ne pou#ons en
effet pas crire :
*nsigned int p%
!or (p & n1+1 % p ,& $ % ++p" 88EXXE?X : p ne pe*t Otre in!Frie*r 9 $
i!(m24ale*rApB L& a*tre-m24ale*rApB"
ret*rn m24ale*rApB @ a*tre-m24ale*rApB%
!e test d&infriorit au sens large est facile$ent obtenu - l&aide des fonctions prcdentes :
bool ETI::operator @& (const ETI I a*tre" const
#
i!(*this && a*tre"
ret*rn tr*e%
ret*rn (*this @ a*tre"%
1
J-L Pris - 27/01/06
1
2
3
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 2 8 1/
Du fait de la disponibilit du constructeur par Dcopie partielleD> la fonction abs(" est tri#iale :
ETI ETI::abs(" const
#
ret*rn ETI(*this, tr*e"%
1
!es tests de supriorit
!es tests de supriorit se laissent facile$ent rduire - des tests d&infriorit :
bool ETI::operator , (const ETI I a*tre" const
#
i!(*this && a*tre"
ret*rn !alse%
ret*rn L (*this @ a*tre"%
1
bool ETI::operator ,& (const ETI I a*tre" const
#
i!(*this && a*tre"
ret*rn tr*e%
ret*rn L (*this @ a*tre"%
1
7 - 'dditions d&"ntiers de Taille Inhabituelle
Co$$e les co$paraisons> les oprations arith$ti.ues l$entaires sont $anifeste$ent re.uises
pour une classe prtendant reprsenter des #aleurs nu$ri.ues. !a gestion du signe i$pli.ue .ue
certaines additions se traduisent par des soustractions.
!&addition sans effet et la fonction aKo*te("
+ne fois carts les cas d&oprandes de signes opposs (3-6)> l&addition re#ient - faire la so$$e des
#aleurs absolues. Co$$e le rsultat doit figurer dans une nou#elle instance de ETI> celle-ci est
cre par copie de l&oprande de droite> puis cha.ue octet de l&oprande de gauche est a3out (en
propageant la retenue #entuelle) - l&octet .ui figure - la $?$e position dans la nou#elle instance.
ETI ETI::operator . (const ETI Ia*tre" const
#
i!(m2positi! II L a*tre-m2positi!"
ret*rn *this + a*tre-abs("% 88 1 . +' && 1 + '
i!(Lm2positi! II a*tre-m2positi!"
ret*rn a*tre + abs("% 88+1 . ' && ' + 1
88les 4ale*rs sont de signes identiG*es, le rFs*ltat a*ra le mOme : +1 . +' && +(1.'"
ETI res*ltat (a*tre"%88on 4a !aire la somme des 4ale*rs absol*es
*nsigned int p%
!or (p & $ % p @ m2taille % ..p"
res*ltat-aKo*te(m24ale*rApB, p"%
ret*rn res*ltat%
1
!&a3out de la #aleur d&un octet - une certaine position dans la reprsentation du rsultat (a#ec
propagation de la retenue si le rsultat dpasse 2//) est confi - une fonction de ser#ice :
4oid ETI::aKo*te(int G*antite, int position"
#
assert(G*antite ,& $ II G*antite @ '(Q"%
i!(m2taille @ position.1" 88on tra4aille s*r m24ale*rApB
redim(position.1, tr*e"% 88/agrandit/ la Jone en conser4ant la 4ale*r
Chile (G*antite , $ II position @ m2taille"
#
G*antite .& m24ale*rApositionB% 88ce G*:on doit reprFsenter
J-L Pris - 27/01/06
1
2
3
4
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 14 8 1/
m24ale*rAposition..B & G*antite P '(Q% 88on reprFsente to*t ce G*:on pe*t
G*antite 8& '(Q% 88on 4a mettre le reste pl*s loin
1
i!(G*antite , $"
#88il en reste encore, mais on n:a pl*s de place car position && m2taille
redim(m2taille.1, tr*e"% 88a*gmente m2taille
m24ale*rApositionB & 1%88propage la reten*e dans le no*4el octet
1
1
!es additions - effet
4oid ETI::operator .& (const ETI I a*tre" 88l:addition d:*n opFrande a4ec e!!et
# *this & *this . a*tre% 1
ETI I ETI::operator .. (" 88incrFmentation prF!ixF
#
i!(m2positi!"
aKo*te(1,$"%
else
enle4e(1,$"%
ret*rn *this%
1
!ors.ue la #aleur est ngati#e> l&incr$enter re#ient - enle#er 1 - sa #aleur absolue> ce .ui peut
?tre effectu en appelant la fonction de ser#ice .ui 3oue> pour la soustraction> un rFle analogue
- celui re$pli par aKo*te(" dans le cas de l&addition.
Co$$e bien sou#ent> l&incr$entation postfixe fait appel - l&oprateur prfix :
ETI ETI::operator .. (int" 88incrFmentation post!ixF
#
ETI a4ant(*this"%
..*this %
ret*rn a4ant%
1
1 - 5oustractions d&"ntiers de Taille Inhabituelle
!a gestion du signe i$pli.ue .ue certaines soustractions se traduisent par des additions.
!a soustraction sans effet et la fonction enle4e("
ETI ETI::operator + (const ETI Ia*tre" const
#
i!(m2positi! II L a*tre-m2positi!"
ret*rn *this . a*tre-abs("% 88 1 + +' && 1 . '
i!(Lm2positi! II a*tre-m2positi!"
ret*rn ETI (abs(" . a*tre, !alse"% 88 +1 + ' & +(1.'"
i!(Lm2positi! II La*tre-m2positi!"
ret*rn ETI (a*tre-abs(" + abs(", !alse"% 88 +1 + +' & +1 . ' && ' + 1
88les de*x 4ale*rs sont positi4es
i! (*this @ a*tre"
ret*rn ETI (a*tre + *this, !alse"% 88 1 N ' & +('N1"
ETI res*ltat (*this"%
*nsigned int p%
!or (p&$ % p @ a*tre-nbHctets?tils(" % ..p"
res*ltat-enle4e(a*tre-m24ale*rApB, p"%
ret*rn res*ltat%
1
!a soustraction de la #aleur d&un octet - une certaine position dans la reprsentation du rsultat
(a#ec propagation d&une retenue #entuelle) est confi - une fonction de ser#ice :
J-L Pris - 27/01/06
9
10
11
12
13
14
15
16
17
1
2
1
2
3
4
5
6
7
8
1
2
3
4
5
6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 11 8 1/
4oid ETI::enle4e(int G*antite, int position"
#
assert(G*antite ,& $ II G*antite @ '(Q"%
assert(m2taille ,& position"%
Chile (G*antite , $"
i! (m24ale*rApositionB ,& G*antite"
#88il n:3 a*ra pas de reten*e
m24ale*rApositionB +& G*antite%
G*antite&$% 88donc c:est !ini
1
else
#88on /empr*nte/ '(Q 9 l:octet s*i4ant
m24ale*rAposition..B .& '(Q + G*antite%
G*antite & 1% 88propage la reten*e
1
1
!es soustractions - effet
4oid ETI::operator +& (ETI a*tre" 88la so*straction d:*n opFrande a4ec e!!et
#
*this & *this N a*tre%
1
ETI I ETI::operator ++ (" 88la dFcrFmentation prF!ixFe
#
i!(m2positi!"
enle4e(1,$"%
else
aKo*te(1,$"% 88dFcrFmenter *n nombre nFgati! a*gmente sa 4ale*r absol*e
ret*rn *this%
1
ETI ETI::operator ++ (int" 88la dFcrFmentation post!ixFe
#
ETI a4ant(*this"%
++*this %
ret*rn a4ant%
1
2 - 6ultiplications d:"ntiers de Taille Inhabituelle
!a $ultiplication est lg@re$ent plus co$plexe .ue l&addition et la soustraction.
!a $ultiplication sans effet et la fonction !oisDe*x("
Eien .ue les #aleurs soient reprsentes en binaire> la procdure habituelle de $ultiplication peut
?tre e$plo,e .uasi$ent telle .uelle. Illustrons> par exe$ple> la $ultiplication de 2/ par 1 :
1 1$$1
* 11$1
a*tre (2/> en binaire)
*this (1> en binaire)
1 1$$1
11 $$1$
11$ $1$$
11$$ 1$$$
<aleurs successi#es a;Ko*ter
1 $1$$ $1$1 res*ltat ()'(, en binaire"
Co$$e les chiffres du $ultiplicateur (*this) ne peu#ent ?tre .ue des 4 et des 1 (on est en
binaire...)> les #aleurs successi#es a;Ko*ter peu#ent ?tre obtenues par double$ent ($ultiplier
par deux re#ient - a3outer un 4 - droite> co$$e $ultiplier par 14 en base 14). Eien entendu> la
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
1
2
3
4
5
6
7
8
1
2
3
4
5
6
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 12 8 1/
so$$e .ui donne le res*ltat ne doit pas inclure les #aleurs de a;Ko*ter .ui correspondent -
un bit nul dans le $ultiplicateur.
Co$$e nous disposons d3- des oprateurs d&addition> il ne nous $an.ue .u&un $o,en de
#rifier la non-nullit de chacun des bits du $ultiplicateur et une fonction doublant la #aleur de
l&instance au titre de la.uelle elle est appele. Cour isoler la #aleur d&un bit particulier d&un octet>
on fait appel - un oprateur (cf. !eGon 2%) .ui effectue un "T logi.ue bit - bit : cha.ue bit du
rsultat sera nul> sauf si les bits correspondants des oprandes sont tous deux non-nuls. Il suffit
donc .ue le second oprande ait un seul bit non-nul (- la position .ui nous intresse) pour .ue la
non nullit du rsultat indi.ue .ue le pre$ier oprande co$porte> lui aussi> un bit non nul -
cette position.
ETI ETI::operator * (const ETI Ia*tre" const
#
const *nsigned char ISH7EAVB & #1, ', W, V, 1Q, )', QW, 1'V1%
ETI a;Ko*ter & a*tre%
ETI res*ltat%
*nsigned int p%
int bit%
!or (p & $ % p @ nbHctets?tils(" % ..p"
!or (bit & $ % bit @ V % ..bit"
#
i!(m24ale*rApB I ISH7EAbitB"
res*ltat .& a;Ko*ter%
a;Ko*ter-!oisDe*x("%
1
res*ltat-m2positi! & (m2positi! && a*tre-m2positi!"%
ret*rn res*ltat%
1
Doubler la #aleur d&un ETI re#ient - doubler (") chacun des octets .ui reprsentent sa #aleur (!-12)>
en #eillant - propager les retenues #entuelles (7# -11# 13-1") :
4oid ETI::!oisDe*x("
#
int p%
bool ilZa?neXeten*e & !alse%
!or(p & $ % p @ nbHctets?tils(" % ..p"
#
bool debordement & (m24ale*rApB ,& 1'V"% 88ie- si le bit de ga*che 4a*t 1
m24ale*rApB *& '% 88aKo*te *n JFro 9 droite (le bit de ga*che est perd*"
i!(ilZa?neXeten*e"
..m24ale*rApB% 88le bit de droite passe de $ 9 1
ilZa?neXeten*e & debordement%
1
i!(ilZa?neXeten*e"
#88le do*blement d* dernier octet a gFnFrF *ne reten*e
i! (p && m2taille" 88to*s les octets disponibles Ftaient *tilisFs
redim(p.1, tr*e"%
m24ale*rApB & 1%
1
1
!a $ultiplication - effet
4oid ETI::operator *& (ETI a*tre"
#
*this & *this * a*tre%
1
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 1 8 1/
14 - Di#isions d:"ntiers de Taille Inhabituelle
!a di#ision enti@re produit $eu% rsultats : le .uotient et le reste. !e .uotient est ren#o, par
l&oprateur 8> alors .ue le reste est ren#o, par l&oprateur P> $ais l&opration sous-3acente est la
$?$e. Il se$ble donc logi.ue d&i$pl$enter ces oprateurs en faisant appel - une seule et
uni.ue fonction de di#ision> .ui ren#oie le .uotient et utilise un pre$ier para$@tre pour spcifier
le di#iseur et un second pour stocHer le reste.
!es di#isions sans et a#ec effet et l&oprateur 7
!&oprateur de di#ision ne s&intresse pas au reste $ais doit> pour satisfaire aux exigences
s,ntaxi.ues de la #ritable fonction de di#ision> disposer d&une #ariable capable de le stocHer :
ETI ETI::operator 8 (const ETI Ia*tre" const
#
ETI reste%
ret*rn di4ise(a*tre, reste"%
1
!a di#ision a#ec effet utilise si$ple$ent la di#ision sans effet et l&affectation :
4oid ETI::operator 8& (const ETI Ia*tre"
#
*this & *this 8 a*tre%
1
!&oprateur $odulo nglige la #aleur ren#o,e par di4ise(" et ren#oie la #aleur place par cette
fonction dans la #ariable reste :
ETI ETI::operator P (const ETI Ia*tre" const
#
ETI reste%
di4ise(a*tre, reste"%
ret*rn reste%
1
!a fonction di4ise("
!a di#ision est confronte - un probl@$e au.uel chappent les autres oprations arith$ti.ues :
elle n&est pas tou3ours dfinie. !a conduite - tenir en cas de tentati#e de di#ision par 9ro est une
.uestion dlicate sur la.uelle nous ne nous tendrons pas trop ici (en particulier parce .ue la
gestion des exceptions ne sera aborde .u&au cours de la !eGon 2). !a fonction di4ise(" se
contente de calculer l&in#erse du no$bre d&octets ncessaires pour reprsenter le di#iseur (3).
!ors.ue le di#iseur est nul> la fonction nbHctets?tils(" ren#oie 4> ce .ui dclenche le
$canis$e pr#u pour grer la di#ision par 4 dans le cas des int. ClutFt .ue de pr#oir sa propre
procdure> la classe ETI e$prunte donc a#eugl$ent aux int leur gestion de la di#ision par 9ro.
!es co$pilateurs actuels proc@dent - une anal,se asse9 pousse du texte source> dans le but
d&opti$iser le code .u&ils gn@rent. +ne #ariable .ui n&est pas relle$ent utilise ris.ue - cette
occasion de disparaKtre pure$ent et si$ple$ent> a#ec les calculs .ui auraient t ncessaires
pour l&initialiser. 5pcifier .u&une #ariable est 4olatile per$et d&indi.uer au co$pilateur .u&il
doit se garder de toute tentati#e d&opti$isation la concernant.
+ne fois carte l&h,poth@se de la di#ision par 4> le probl@$e est de sa#oir co$bien de fois ou peut
soustraire le di#iseur du di#idende (ce .ui nous donnera le .uotient) et co$bien il restera apr@s la
derni@re soustraction (ce .u&on appelle> 3uste$ent> le reste).
'borde ainsi> la di#ision est facile - progra$$er> $ais tr@s lente du fait du no$bre sou#ent
considrable de soustractions re.uises. !a #ersion .ue nous allons utiliser li$ite le no$bre de
soustractions en utilisant une opration .ue nous sa#ons effectuer relati#e$ent rapide$ent : le
double$ent d&une #aleur. ClutFt .ue de soustraire le di#iseur> elle soustrait (21) la plus grande
#aleur possible obtenue par double$ents successifs (12-1) de ce di#iseur (le no$bre - a3outer au
.uotient (22) pour reflter cette soustraction n&est donc pas 1> $ais 1 doubl (1") autant de fois
J-L Pris - 27/01/06
1
2
3
4
5
1
2
3
4
1
2
3
4
5
6
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 1% 8 1/
.ue l&a t le di#iseur). !e reste obtenu apr@s cette soustraction est en gnral plus grand .ue le
di4ise*r> et il faut lui r-appli.uer l&opration autant de fois .ue ncessaire (7-23).
ETI ETI::di4ise(const ETI Ia*tre, ETI I reste" const
#
88r*n+time error dFlibFrFe en cas de di4ision par $ :
4olatile int x & 18a*tre-nbHctets?tils("%
reste & abs("%
const ETI di4ise*r(a*tre-abs(""%
ETI G*otient%
Chile(reste ,& di4ise*r"
#
ETI petite(di4ise*r"%
ETI grande & petite%
ETI aKo*t(1"%
Chile (grande @& reste"
#
grande-!oisDe*x("%
i!(grande @& reste"
#
petite & grande%
aKo*t-!oisDe*x("%
1
1
reste +& petite%
G*otient .& aKo*t%
1
ret*rn ETI(G*otient, m2positi! && a*tre-m2positi!"%
1
11 - Reprsentation textuelle d&un "ntier de Taille Inhabituelle
!a prsentation des #aleurs de t,pe ETI sous une for$e intelligible pour un ?tre hu$ain exige la
cration d&une chaKne de caract@res. Cette cration exige une succession de di#isions par 14 .ui
peut conduire - des te$ps d&excution i$pressionnants...
QString ETI::texte(" const
#
const ETI DI[(1$"%
QString chaine%
ETI 4al(*this"%
ETI reste%
Chile (4al-nbHctets?tils(" L& $"
#
4al & 4al-di4ise(DI[, reste"%
QEhar chi!!re & reste-m24ale*rA$B . :$:%
chaine & chi!!re . chaine%
1
ret*rn m2positi! M chaine : /+/ . chaine%
1
Cette fonction est le seul $e$bre de la classe ETI .ui dpende de la librairie =t. Cour exploiter
les ETI en l&absence de =t> il faudra donc $odifier le t,pe de la fonction texte(" et celui de ses
#ariables chaine et chi!!re.
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<C++ 0.4 - =t >2 TD 17 : "ntiers de Taille Inhabituelle 1/ 8 1/
12 - !e fichier eti.h
+ne fois dfinies toutes les fonctions $e$bre .ue nous #enons de dcrire > #otre fichier eti.h
de#rait a#oir l&aspect sui#ant :
\incl*de /Gstring-h/
class ETI
#
p*blic:
88constr*ction et Eie
ETI("%
ETI(const ETI I modele"%
ETI(const ETI I 4ale*r, bool signe"%
ETI(const char * s"%
ETI(int 4"%
SETI("%
static ETI hasard(*nsigned long t"%
88a!!ectation
ETI I operator &(const ETI I a*tre" %
88comparaisons et 4ale*r absol*e
bool operator && (const ETI I a*tre" const%
bool operator L& (const ETI I a*tre" const%
bool operator @ (const ETI I a*tre" const%
bool operator @& (const ETI I a*tre" const%
ETI abs(" const%
bool operator , (const ETI I a*tre" const%
bool operator ,& (const ETI I a*tre" const%
88additions
ETI operator . (const ETI Ia*tre" const%
4oid operator .& (const ETI Ia*tre"%
ETI I operator .. ("% 88prF!ixF
ETI operator .. (int"% 88post!ixF
88so*stractions
ETI operator + (const ETI Ia*tre" const%
4oid operator +& (ETI a*tre"%
ETI I operator ++ ("% 88prF!ixF
ETI operator ++ (int"% 88post!ixF
88m*ltiplications
ETI operator * (const ETI Ia*tre" const%
4oid operator *& (ETI a*tre"%
88di4isions
ETI operator 8 (const ETI Ia*tre" const%
ETI operator P (const ETI Ia*tre" const%
4oid operator 8& (const ETI Ia*tre"%
88reprFsentation text*elle
QString texte(" const%
protected:
*nsigned int m2taille%
*nsigned char * m24ale*r%
bool m2positi!%
88!onctions de ser4ice
4oid base;lloc(*nsigned int t&1"%
*nsigned int ETI::nbHctets?tils(" const%
4oid redim(*nsigned int no*4elleTaille, bool conser4er6ale*r"%
4oid aKo*te(int G*antite, int position"%
4oid enle4e(int G*antite, int position"%
4oid !oisDe*x("%
ETI di4ise(const ETI Ia*tre, ETI I reste" const%
1%
J-L Pris - 27/01/06
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

You might also like