Sunteți pe pagina 1din 29

Capitolul 1

CALCULUL ÎN VIRGULĂ MOBILĂ

1.1 Aritmetica în virgulă mobilă


Rezolvarea diferitelor probleme cu ajutorul calculatorului numeric depinde, într-o prima
instanţă, de posibilitatea de a reprezenta numerele în maşina de calcul folosită. Această
posibilitate depinde de tipul numerelor şi de structura constructivă (“hardware”) a
echipamentului de calcul, anume: baza de reprezentare a numerelor (baza maşinii de calcul) şi
lungimea cuvântului de memorie. Ca urmare, se poate reprezenta un număr finit de cifre în
sistemul de numeraţie folosit. Din acest punct de vedere, numerele întregi şi cele reale suferă un
tratament diferit, după cum se detaliază în continuare.
Astfel, numerele întregi reprezentabile în calculator, care formează mulţimea notată cu I,
constituie o submulţime finită a mulţimii numerelor întregi Z: I ⊂ Z . Reprezentarea acestor
numere este exactă, iar aritmetica cu aceste numere este de asemenea exactă, excepţie facând
operaţia de împărţire, în general.
Astfel, domeniul valorilor întregi reprezentabile în calculatorul numeric este:
I = {z ∈ Z / m I ≤ z ≤ M I } ,

unde mărimile m I şi M I depind de următoarele: spaţiul de memorie pus la dispoziţie pentru


acest tip de numere, baza de numeraţie folosită, precum şi modul de reprezentare a acestor
numere. Notând cu α baza de reprezentare a numerelor întregi şi cu t I numărul de cifre în
baza α care pot fi reprezentate pe un cuvânt sau multiplu de cuvânt de memorie, se pot scrie
relaţiile:

m I = − α t I −1 , M I = α t I −1 − 1 .
Dacă baza de numeraţie este doi şi sunt t I =16 cifre binare, atunci domeniul de
reprezentare pentru numere întregi este cuprins între − 215 şi 215 −1 . Dacă numărul de cifre
binare este t I = 32 , atunci domeniul de reprezentare este cuprins între − 2 31 şi 2 31 −1 .
Încercarea de a opera cu numere care nu aparţin domeniului I de reprezentare, determină, la
majoritatea calculatoarelor numerice, emiterea unor mesaje de eroare fatală, programele
implicate fiind abandonate: “depăşire (binară) inferioară” (dacă z < m I ), respectiv “depăşire
(binară) superioară” (dacă z > M I ).
Uzuală este reprezentarea în baza de numeraţie doi, alocându-se o cifră binară pentru semn şi
t I −1 cifre pentru număr, anume reprezentarea în cod complementar faţă de baza α definită
2 1. Calculul în virgulă mobilă

astfel:

 z, z≥0
z c =  tI .
α − | z |, z < 0
Spre deosebire de numerele întregi, în general numerele reale se reprezintă aproximativ în
calculatorul numeric. În continuare se definesc două submulţimi ale numerelor reale şi anume:
• submulţimea G care conţine numerele reale care s-ar putea reprezenta în calculatorul
numeric;
• submulţimea F care conţine numerele reale care se reprezintă efectiv în calculatorul
numeric.
În timp ce mulţimea G, ca şi mulţimea numerelor reale ℜ, are un număr infinit de
elemente, mulţimea F are un număr finit de elemente, relaţia care se poate scrie între aceste
mulţimi fiind: F ⊂ G ⊂ ℜ . Metoda cea mai larg folosită pentru reprezentarea numerelor reale
în calculator, numere care aparţin mulţimii F, este cea a virgulei mobile.
Definiţie:
Prin aritmetica virgulei mobile se înţeleg următoarele:
(a) un model matematic de reprezentare a numerelor (definirea mulţimii F);
(b) o modalitate de reprezentare a numerelor din mulţimea G în calculatorul numeric, altfel
spus o modalitate de implementare în calculator a modelului (definirea operatorului de
rotunjire, notat cu fl);
(c) operaţiile elementare: adunarea, scăderea, înmulţirea şi împărţirea definite cu numerele
mulţimii F.
Acestea sunt detaliate în secţiunile următoare ale acestui subcapitol.

1.1.1 Numere în virgulă mobilă

Conceptul de număr în virgulă mobilă se poate introduce prin exemplul următor.


Exemplul 1.1:
Fie numărul real x =1234 ,56789 . Acesta se poate scrie şi sub următoarele forme:
x =1234 ,56789 ×10 0 =123456789 ,0 ×10 −5 = 0,0012345678 9 ×10 6 =
= 0,123456789 ×10 4
Corespunzător ultimei forme scrise, se denumesc şi se notează următoarele elemente:
• mantisă (fracţie), notată cu f, reprezentând numărul fracţionar;
• exponent, notat cu e, reprezentând exponentul la care este ridicată baza de numeraţie
folosită;
• baza de numeraţie, notată cu β , în cazul de faţă egală cu 10;
• numărul cifrelor mantisei, notat cu litera t.
Rezultă, aşadar, că poziţia virgulei poate fi modificată, cu adaptarea corespunzătoare a
exponentului. Din acest punct de vedere, se spune că numerele întregi tratate anterior sunt
reprezentate în virgulă fixă.
1.1 Aritmetica în virgulă mobilă 3

Definiţie:
O mulţime de numere în virgulă mobilă este definită prin următorii parametri:
(a) β- baza maşinii de calcul;
(b) t - numărul de cifre în baza βutilizate pentru a reprezenta partea fracţionară (precizia
maşinii de calcul);
(c) L - cel mai mic exponent (limita de depăşire inferioară);
(d) U - cel mai mare exponent (limita de depăşire superioară).
Exponentul e este cuprins între valorile: L ≤ e ≤ U .
Definiţie:
Mulţimea F de numere în virgulă mobilă este:
F ={x ∈ℜ/ x = f ⋅ βe } ∪{0} , unde:
d d d 
f = ± 1 +  + ii +  + tt , 0 ≤ d i ≤ β − 1, i = 1,  , t

β β β 
L≤e≤U
unde f este mantisa (fracţia), e este exponentul, βeste baza maşinii, t este numărul de cifre în
baza βşi d i sunt cifrele bazei.

Dacă pentru orice x∈ F \ {0} , prima cifră a fracţiei, d 1 , este diferită de zero, atunci se spune
că sistemul de numere în virgulă mobilă este normalizat. În acest caz, poate fi scrisă relaţia:
1 / β≤| f |<1 .

Orice număr x∈ F \ {0} este cuprins între două valori extreme:


m ≤| x |≤ M
M = βL −1 , M = βU ⋅ (1 − β−t )

Acestea se numesc: m – cel mai mic număr real pozitiv reprezentabil, iar M – cel mai mare
număr real pozitiv reprezentabil. În acest caz, mulţimea G se poate defini ca fiind:
G = {x ∈ℜ/ m ≤| x |≤ M} ∪{0} = [ −M,−m] ∪{0} ∪[m, M ] .

Încercarea de a opera cu numere nenule care nu se încadrează între aceste limite conduce,
pentru majoritatea calculatoarelor numerice, la emiterea unor mesaje de eroare fatală, care vor
determina abandonarea programului: “depăşire flotantă inferioară” (dacă | x |< m ), respectiv
“depăşire flotantă superioară” (dacă | x |> M ). În unele implementări, se atribuie valoarea zero
pentru numerele din prima categorie menţionată, fără emiterea mesajului de eroare, împreună cu
emiterea unui mesaj de avertizare.
Exemplul 1.2:
4 1. Calculul în virgulă mobilă

Se consideră o mulţime de numere în virgulă mobilă normalizată cu următorii parametri:


β= 2 , t = 3 , L = −1 , U = 2 . Rezultă, conform relaţiilor scrise mai sus: m = 1 / 4 şi
M = 7 / 2 . Elementele mulţimii F sunt în acest caz:
±.100 ×2 e , ±.101 ×2 e , ±.110 ×2 e , ±.111 ×2 e , e ∈{−1, 0, 1, 2} .

Numărul elementelor mulţimii F este: card ( F) =33 . Elementele pozitive ale mulţimii F
sunt prezentate în Figura 1.1.

1 7
m= M=
4 2

0 2-2 2-1 20 21

Fig. 1.1 Elementele pozitive ale mulţimii numerelor în virgulă mobilă


( β=2 , t = 3 , L = −1 , U = 2 , reprezentare normalizată)

Mulţimea F este o mulţime finită. Între puterile succesive ale lui βnumerele din mulţimea
F sunt echidistante, numărul acestora fiind constant. Numărul de elemente ale lui F este dat de
relaţia:
card ( F) = 2 ⋅ βt −1 ⋅ (β −1) ⋅ ( U − L +1) +1 ,

în care mărimea βt −1 ⋅ (β−1) =βt −βt −1 reprezintă numărul constant de elemente dintr-un
interval definit de către două puteri succesive ale bazei βşi U − L + 1 reprezintă numărul de
intervale determinate de către puterile succesive ale lui β . Produsul acestora este multiplicat
cu 2 pentru a include atât numerele pozitive, cât şi pe cele negative. Valoarea 1 este adăugată
pentru elementul 0.
Concluzii:
(a) Numerele aparţinând mulţimii F nu sunt echidistante în domeniul lor de existenţă; acestea
sunt mai “dese” în apropierea originii (puterile lui βscad) şi mai “rare” spre extremităţile
mulţimii F (puterile lui βcresc).
(b) Numerele sunt echidistante numai între puterile succesive ale lui β .
(c) Datorită faptului că mulţimea F are un număr finit de elemente, nu se pot reprezenta
continuu, în detaliu, toate numerele reale; mai mult, fiecare număr din mulţimea F este
asociat unui întreg interval din mulţimea G, deci unui întreg interval de numere reale.
Uzuală este reprezentarea normalizată în baza de numeraţie doi, alocându-se o poziţie binară
pentru semn, un număr de poziţii binare pentru exponent şi t cifre binare pentru mantisă.
Deoarece tipul de semn al numărului este memorat, pentru fracţie se realizează o reprezentare a
întregului d 1d 2  d t ⋅ β t (valoarea absolută a mantisei). De asemenea, pentru a nu se memora
semnul şi pentru exponent, se reprezintă un număr întreg pozitiv: C = e + E ≥ 0 , mărimea E
numindu-se deplasament, iar mărimea C numindu-se caracteristică. Cum reprezentarea este
normalizată, prima cifră a fracţiei este d 1 =1 şi nu se mai reprezintă. Astfel, se câştigă încă o
1.1 Aritmetica în virgulă mobilă 5

poziţie binară pentru fracţie. Se spune că se realizează o reprezentare normalizată cu “poziţie


binară ascunsă” (în limba engleză, “hidden bit”).
Exemplul 1.3:
Pentru β=2 şi 32 de poziţii binare pentru un număr real, reprezentarea se realizează în
simplă precizie, iar pentru 64 de poziţii binare pentru un număr real, reprezentarea se realizează
în dublă precizie.
După standardul IEEE (abreviere din limba engleză, “the Institute of Electrical and
Electronics Engineers” Inc. USA), pentru β=2 rezultă t = 24 , L = −126 şi U =127
pentru reprezentarea în simplă precizie şi t = 53 , L = −1022 , U =1023 pentru
reprezentarea în dublă precizie. Rezultă, de asemenea, pentru reprezentarea în simplă precizie:
m ≅10 −38 şi M ≅10 +38 , iar pentru reprezentarea în dublă precizie: m ≅10 −308 şi
M ≅10 +308 .

1.1.2 Reprezentarea aproximativă a numerelor. Scheme de rotunjire

Oricare ar fi un număr x ∈G , x ≠ 0 , acesta poate fi scris sub forma:


x =f ⋅ βe + g ⋅ βe −t . (1.0)
Se vor considera fracţiile normalizate, deci sunt îndeplinite relaţiile:
1 / β ≤| f |<1, 0 ≤| g |<1 .
Nu toate numerele din mulţimea G se pot reprezenta exact, datorită faptului că numai t cifre
în baza βpot fi reţinute pentru fracţie. În aceste condiţii, se spune că numărul este reprezentat
aproximativ (rotunjit). Se defineşte operatorul de rotunjire fl: fl : G → F . Există mai multe
modalităţi de definire a acestuia şi anume:
(a) rotunjirea prin tăiere (trunchiere): fl(x) este cel mai apropiat element c ∈F , de x ∈ G ,
cu proprietatea | c |≤| x | .
Această modalitate de rotunjire este ilustrată în Figura 1.2. Astfel, oricare ar fi numărul
x ∈[c 2 , c 3 ) , acesta va fi reprezentat prin elementul c 2 . Expresia aproximantului pentru
numărul real x este: fl ( x ) =f ⋅βe .

c1 c2 c3 ∈ F

Fig. 1.2 Principiul rotunjirii prin tăiere (trunchiere): fl ( x ) = c 2 , ∀x ∈[c 2 , c 3 )

Exemplul 1.4:
Se consideră un sistem de numere în virgulă mobilă cu β=10 , t = 4 . Fie numărul
x =12945 ,734 . Numărul x se poate scrie sub forma (1.1):
x = 0,12945734 ⋅10 5 = 0,1294 ⋅10 5 + 0,5734 ⋅10 5−4 ,
6 1. Calculul în virgulă mobilă

unde f =0,1294 ; e =5; g =0,5734 . Rezultă, aşadar, valoarea reţinută pentru reprezentare
şi rotunjită prin tăiere: fl ( x ) =0,1294 ⋅10 5 . Aceasta corespunde numărului 12940 ≠ x .
(b) rotunjirea simetrică: fl(x) este cel mai apropiat element c ∈F , de x ∈ G (a se vedea
Figura 1.3).
Analizând Figura 1.3, rezultă că oricare ar fi numerele x şi y din intervalul definit de
elementele aflate la mijlocul intervalelor (c1 , c 2 ) şi, respectiv, (c 2 , c 3 ) , acestea vor fi
reprezentate prin elementul c 2 al mulţimii F, expresia pentru fl(x) fiind în acest caz:

 β
f ⋅ βe , | g |< 0,
 2.
fl( x ) = 
f ⋅ β e ± β e −t , | g |≥ 0, β

 2
În ultima expresie, semnul “+” se consideră pentru f > 0 şi semnul “-“ se consideră pentru
f <0 .

x y

c1 c2 c3 ∈ F

Fig. 1.3 Principiul rotunjirii simetrice:


fl ( x ) = c 2 , fl ( y) = c 2 ; ∀x ∈(( c1 + c 2 ) / 2, c 2 ), ∀y ∈(c 2 , (c 2 + c 3 ) / 2)

Neajunsul acestei maniere de reprezentare constă în faptul că dacă numărul x este situat la
jumătatea distanţei dintre două numere consecutive din mulţimea F, atunci fl(x) poate lua
oricare din cele două valori învecinate.
(c) rotunjirea uniformă (metoda cifrei pare)
În acest caz, fl(x) are următoarea expresie:
 β
f ⋅ βe , | g |< 0,
 2
f β
 ⋅ β e ± β e−t , | g |> 0,
fl( x ) =  2 .
f β
⋅ β e ± β e−t , | g |= 0, , ultima cifra f − impara
 2
 β
f ⋅ βe , | g |= 0, , ultima cifra f − para
 2
În această expresie de definiţie, semnul “+” se consideră pentru f > 0 şi semnul “-“ se
consideră pentru f < 0 . Această modalitate de reprezentare este adoptată şi de standardul
IEEE.
1.1 Aritmetica în virgulă mobilă 7

Exemplul 1.5:
Se consideră β=10 , t = 4 şi o rotunjire uniformă.
(a) x =12944 ,9942 = 0,1294 ⋅10 5 + 0,4994 ⋅10 5−4 .
Se observă că |g| este mai mic decât 0.5, deci:
fl ( x ) = 0,1294 ⋅10 5 ( =12940 ≠ x ) .
(b) x =129551 = 0,1295 ⋅10 6 + 0,51 ⋅10 6 −4 .
Se observă că |g| este mai mare decât 0.5, deci:
fl ( x ) = 0,1295 ⋅10 6 +10 6 −4 ( =129600 ≠ x) .
4 4 −4
(c) x =1297 ,5 = 0,1297 ⋅10 + 0,5 ⋅10 .
Se observă că |g| este egal cu 0.5 şi ultima cifră a lui f este impară, deci:
fl ( x ) = 0,1297 ⋅10 4 +10 4 −4 (=1298 ≠ x ) .
(d) x =1296 ,5 = 0,1296 ⋅10 4 + 0,5 ⋅10 4 −4 .
Se observă că |g| este egal cu 0.5 şi ultima cifră a lui f este pară, deci:
fl ( x ) = 0,1296 ⋅10 4 ( =1296 ≠ x ) .

În continuare se consideră mulţimea F împreună cu o rotunjire fixată. În plus, se consideră


orice număr nenul aparţinând mulţimii G, pentru care există reprezentare în mulţimea F:
∀x ∈G , x ≠ 0, ∃fl ( x ) ∈F . Cum, în general, numărul x aparţinând mulţimii G se
reprezintă aproximativ, se pot defini următoarele două tipuri de erori:
(a) eroarea absolută, notată e x :
e x =| x − fl ( x ) | ;

(b) eroarea relativă, notată εx :


ε x = e x / | x |≅ e x / | fl( x ) |=| x − fl ( x ) | / | fl( x ) | .

În expresia anterioară, |x| s-a aproximat prin |fl(x)| deoarece, în general, valoarea x nu se
cunoaşte în sensul că nu se poate reprezenta exact în calculator. Se demonstrează că eroarea
relativă maximă se produce când f ia cea mai mică valoare şi g ia cea mai mare valoare, adică
f =1 / β şi g =1 :

| x − fl ( x ) | | f ⋅ βe + g ⋅ βe −t − fl ( x ) | 1 ⋅ βe −t
εx = = ≤k ⋅ ≅ k ⋅ β1−t ,
| fl( x ) | | fl ( x ) | (1 / β) ⋅ βe
1−t
unde β este o mărime specifică maşinii de calcul, ea caracterizând precizia relativă de
reprezentare. Această mărime se mai numeşte şi cea mai mare spaţiere relativă şi este asociată
cu rotunjirea prin tăiere, pentru care k = 1 . Pentru rotunjirea simetrică, rezultă k =1 / β şi
atunci eroarea relativă maximă are valoarea β−t , mărime denumită cea mai mică spaţiere
relativă.
Definiţiile anterioare se pot extinde imediat la cazul vectorial, pentru elemente dintr-un
spaţiu vectorial normat (a se vedea Anexa A). Astfel, considerând vectorul cu componente reale
x = [ x 1  x n ] T , unde “T” reprezintă operaţia de transpunere vectorială, se definesc
următoarele:
8 1. Calculul în virgulă mobilă

(a) eroarea absolută (vectorială):


e x ,α =|| x − FL ( x ) || α , FL ( x ) =[fl ( x 1 )  fl ( x n )] T ,

unde || . || α este o normă vectorială uzuală;


(b) eroarea relativă (vectorială):
εx ,α = e x ,α / || FL ( x ) || α .

1.1.3 Operaţii elementare în virgulă mobilă

Se definesc operaţiile elementare care au loc cu elementele unei mulţimi F de numere în


virgulă mobilă. Aceste modalităţi de definire sunt implementate uzual în calculatoarele
numerice.
A. Adunarea
B. Oricare ar fi două numere x şi y din mulţimea G, pentru care există fl(x) şi fl(y) aparţinând
mulţimii F, numărului x + y i se asociază numărul fl( x + y ) obţinut prin aplicarea
următorului algoritm:
Pas 1: se reprezintă intern numerele x şi y prin fl(x) şi, respectiv, fl(y).
Pas 2: dacă numerele au exponent diferit, atunci numărul cu exponent mai mic se aduce la o
formă în care exponentul să fie egal cu cel al celuilalt termen, operaţiune care se numeşte
denormalizare. Acest lucru se realizează prin deplasarea mantisei spre dreapta, inserând
zerouri după virgulă.Astfel, se deplasează mantisa atâtea poziţii câte sunt necesare pentru
a creşte exponentul la valoarea exponentului celuilalt termen.
Pas 3: se adună mantisele şi din rezultat se păstrează t cifre.
Pas 4: dacă este necesar, se normalizează rezultatul.
Observaţii:
1. Deplasarea mantisei spre dreapta determină creşterea exponentului, iar deplasarea spre
stânga a mantisei determină scăderea exponentului.
2. Scăderea se realizează la fel ca adunarea, cu deosebirea că mantisele se scad. În fapt,
scăderea reprezintă o adunare în care scăzătorul are semn schimbat.
Consecinţa esenţială a acestui mod de definire este aceea că, spre deosebire de aritmetica
reală, adunarea în virgulă mobilă nu este asociativă.
Exemplul 1.6:
Se consideră o aritmetică a virgulei mobile cu β=10 , t = 3 , reprezentare normalizată şi
rotunjire prin tăiere. Fie calculul: 0,001 +1 −1 . Asociind primii doi termeni, se ajunge la
rezultatul fl (fl (10 −3 +1) −1) =0 , care este eronat. În cazul asocierii ultimilor doi termeni se
obţine: fl (10 −3 +fl (1 −1)) =10 −3 , care este rezultatul corect.
Exemplul 1.7:
Se consideră o aritmetică a virgulei mobile cu β=10 , t = 3 , reprezentare normalizată şi
1.1 Aritmetica în virgulă mobilă 9

rotunjire prin tăiere. Fie calculul: 1,001 −1 . Se obţine: fl (1,001 −1) =0 , rezultat eronat.
Exemplele 1.6 şi 1.7 pun în evidenţă două fenomene nedorite şi generatoare de erori, care
pot apare la efectuarea unei adunări în virgulă mobilă:
(a) omiterea catastrofală: apare atunci când se adună doi termeni şi valoarea absolută a unui
termen este mai mică decât precizia de reprezentare a celuilalt termen; în acest caz,
rezultatul este dat de termenul cu valoare absolută mai mare (această situaţie este ilustrată
în Exemplul 1.6).
(b) neutralizarea termenilor: apare atunci când se adună numere cu semne diferite şi cu
valori absolute apropiate; în acest caz, în mod eronat, rezultatul este nul (această situaţie
este ilustrată în Exemplul 1.7).
Precizia calculelor numerice este caracterizată de două mărimi constante a căror valoare este
dependentă de tipul maşinii de calcul folosite. Cele două valori menţionate, numite şi “constante
de maşină”, sunt introduse prin următoarea definiţie.
Definiţie:
Epsilonul maşină pentru adunare (notat ε+
m ) reprezintă cel mai mic număr real pozitiv

reprezentabil care schimbă, prin adunare, unitatea maşinii de calcul: fl (1 + ε+


m ) >1 .

Epsilonul maşină pentru scădere (notat ε−


m ) reprezintă cel mai mic număr real pozitiv

reprezentabil care schimbă, prin scădere, unitatea maşinii de calcul: fl (1 − ε−


m ) <1 .

În Figura 1.4 sunt ilustrate cele două definiţii. Conform Figurii 1.4, sunt îndeplinite
relaţiile:
• adunare: fl (1 + ε+m ) >1, fl (1 + c) =1 ;
• scădere: fl (1 − ε+m ) <1, fl (1 − c) =1 .

c ∈F εm- εm+ 1

Fig. 1.4 Conceptul de epsilon maşină

Astfel, rezultă că cele două mărimi au valorile: ε+m = β1−t , ε −m = β−t .


Se demonstrează că, pentru o aritmetică a virgulei mobile cu β=2 , este îndeplinită relaţia:
ε m = 2 ⋅ ε −m .
+

Exemplul 1.8:
Valorile celor două constante de maşină, în standardul IEEE, sunt următoarele:
• pentru reprezentarea în simplă precizie:
ε −m = 5.96 ⋅ 10 −8 ; ε +m = 1.19 ⋅ 10 −7 ;

• pentru reprezentarea în dublă precizie:


10 1. Calculul în virgulă mobilă

ε −m = 1.11 ⋅ 10 −16 ; ε +m = 2.22 ⋅ 10 −16 .

Următorul algoritm, descris în limbaj pseudocod (a se vedea Anexa B), descrie modul de
calcul al epsilonului maşină pentru adunare, rezultatul final gasindu-se în variabila eps_p:
atribuie eps_p ← 1
cât timp ( 1 + eps _ p > 1 ) execută
 atribuie eps_p ← 0.5*eps_p

atribuie eps_p ← 2*eps_p.

C. Înmulţirea
Oricare ar fi x şi y, două numere din mulţimea G, pentru care există fl(x) şi, respectiv, fl(y)
aparţinând multimii F, numărului x ⋅ y i se asociază numărul fl ( x ⋅ y) , care se determină cu
algoritmul următor:
Pas 1: se reprezintă intern numerele x şi y prin fl(x) şi, respectiv, fl(y).
Pas 2: se înmulţesc fracţiile şi se adună exponenţii.
Pas 3: din fracţia rezultată se opresc t cifre.
Pas 4: dacă este necesar, se normalizează rezultatul.
Observaţii:
1. Înmulţirea nu este asociativă.
2. Împărţirea se realizează în aceeaşi manieră ca şi înmulţirea, cu deosebirea că la pasul 2
mantisele se împart, iar exponenţii se scad.
Exemplul 1.9:
Se consideră o aritmetică a virgulei mobile cu β=10 , t = 3 , reprezentare normalizată şi
rotunjire prin tăiere. Fie x = 22 ,547 şi y = 0,43936 . Rezultă fl ( x ⋅ y) = 9,900 .

1.2 Propagarea erorilor în calculele numerice


În general, în cursul rezolvării unei probleme cu ajutorul calculatorului numeric, precizia
calculelor este influenţată de mai mulţi factori. Astfel, eroarea totală dintr-un calcul numeric
este generată de trei surse principale de erori:
(a) erori inerente;
(b) erori de metodă (de calcul);
(c) erori de reprezentare.
Erorile inerente provin din datele iniţiale ale problemei de rezolvat (date care pot fi
rezultatele unor măsurători experimentale sau ale altor calcule anterioare) şi/sau erorile
provenite din faptul că se lucrează cu un model aproximativ al fenomenului real implicat în
problema de rezolvat.
Erorile de metodă (sau de trunchiere) sunt datorate metodei numerice utilizate. În general,
este necesar un număr mare de operaţii pentru a putea ajunge la soluţia exactă (de regulă, atunci
1.1 Aritmetica în virgulă mobilă 11

când o expresie de calcul conţine o infinitate de termeni) şi calculele sunt oprite, în funcţie de
un anumit criteriu, atunci când se ajunge la o anumită precizie acceptabilă (aşadar
conştientizată).
Erorile de reprezentare sunt datorate posibilităţii efective de a reprezenta numerele în
calculatorul numeric. Acest tip de erori se manifestă în datele iniţiale, intermediare şi în cele de
ieşire care constituie rezultatele finale.
Definiţie:
Se numeşte calcul aproximativ, un calcul efectuat într-o aritmetică a virgulei mobile.
Fie x şi y două numere aparţinând mulţimii G şi reprezentate în mulţimea F prin fl(x) şi,
respectiv, fl(y). Fie ∗ una din operaţiile elementare definite anterior. Atunci, pot fi scrise
următoarele relaţii:
x = fl ( x ) + e x , y = fl ( y) + e y , εx = e x / fl ( x ), ε y = e y / fl ( y) ,
x ∗ y = fl ( x ∗ y) + e x ∗y , εx∗y = e x∗y / fl ( x ∗ y) .

Se acceptă ca postulat următoarea afirmaţie: eroarea relativă într-un calcul aproximativ cu


numere aproximative este egală cu suma dintre eroarea relativă produsă de calculul exact
respectiv cu numere aproximative ( T1 ) şi eroarea relativă produsă de calculul aproximativ cu
numerele exacte corespunzătoare ( T2 ).
Acest postulat, descris de către relaţia:
εx∗y = T1 + T2 ,
permite determinarea modalităţii de propagare a erorilor relative pentru operaţiile efectuate în
virgulă mobilă, după cum urmează.
Pentru calculul exact cu numere aproximative (termenul T1 ), rezultă:
e x ≠ 0, e y ≠ 0, fl ( x ∗ y) = fl ( x ) ∗ fl ( y),
T1 = k 1 ⋅ εx + k 2 ⋅ εy .

Constantele k 1 şi k 2 au valori diferite, în funcţie de operaţia efectuată:


• pentru adunare:
fl ( x ) fl ( y)
k1 = , k2 = ;
fl ( x ) + fl ( y ) fl ( x ) + fl ( y)

• pentru scădere:
fl ( x ) fl ( y)
k1 = , k 2 =− ;
fl ( x ) − fl ( y) fl ( x ) − fl ( y)

• pentru înmulţire:
k1 = k 2 = 1 ;

• pentru împărţire:
k 1 = 1, k 2 = −1 .
12 1. Calculul în virgulă mobilă

Pentru calculul aproximativ cu numere exacte (termenul T2 ), rezultă:


e x = 0, e y = 0, fl ( x ∗ y) ≠ fl ( x ) ∗ fl ( y),

şi atunci:
T2 ≤ k ⋅ β1−t ,

ca pentru orice număr real care nu se reprezintă exact.


Exemplul 1.10:
Se consideră evaluarea următorului polinom:
y( x ) = x 7 − 7 ⋅ x 6 + 21 ⋅ x 5 − 35 ⋅ x 4 + 35 ⋅ x 3 − 21 ⋅ x 2 + 7 ⋅ x − 1 ,
pentru valori ale variabilei x în intervalul [0.998,1.012] şi utilizând un pas de evaluare egal cu
0.0001. Figura 1.5 ilustrează cu linie punctată rezultatul calculelor în dublă precizie (standardul
IEEE) utilizând formula de mai sus, cu linie continuă fiind reprezentate rezultatele corecte.
Acestea din urmă sunt obţinute evaluând polinomul y( x ) =( x −1) 7 .
-14
x 10
5

-1

-2

-3

-4

-5
0.985 0.99 0.995 1 1.005 1.01 1.015

Fig. 1.5 Ilustrarea propagării erorilor într-un calcul numeric

Analizând Figura 1.5, se remarcă faptul că valorile calculate sunt de ordimul a 10 −14 , ceea
ce evidenţiază erori relativ mici între rezultatele celor două maniere de calcul. Aceste diferenţe
se explică prin fenomenele de neutralizarea termenilor şi omitere catastrofală.

Cele expuse până acum demonstrează faptul că într-un calcul numeric erorile se propagă de
la o operaţie la alta. Pe măsură ce numărul operaţiilor dintr-un calcul creşte, pot apare situaţii în
care erorile se acumulează excesiv de mult, fapt care determină obţinerea unei valori total
1.1 Aritmetica în virgulă mobilă 13

incorecte a rezultatului final. Ca urmare, la întocmirea unui algoritm de calcul şi apoi la


implementarea acestuia într-un program, utilizatorul trebuie să se asigure că soluţiile nu vor fi
afectate de erori care să depăşească anumite limite admisibile.
Se pot formula următoarele reguli generale pentru mărirea preciziei calculelor:
1. când se adună sau se scad numere, este recomandabil să se înceapă cu cele mai mici în
valoare absolută, separat pentru cele negative şi separat pentru cele pozitive;
2. dacă este posibil, este recomandabil să se evite scăderea a două numere aproximativ egale;
o expresie care conţine o astfel de scădere poate fi rescrisă.
3. o expresie de forma (a − b) ⋅ c poate fi rescrisă sub forma a ⋅ c − b ⋅ c , iar o expresie de
forma (a − b) / c poate fi rescrisă sub forma a / c − b / c ; dacă numerele a şi b sunt
aproximativ egale, este recomandabil să se efectueze mai întâi scăderea şi apoi înmulţirea
sau împărţirea;
4. dacă regulile generale anterior enunţate nu se pot aplica, atunci se va urmări minimizarea
numărului de operaţii aritmetice implicate.
Exemplul 1.11:
Se consideră următoarele relaţii de calcul:
h =1 / 2, x = 2 / 3 − h, y = 3 / 5 − h, e = x + x + x − h,
f = y + y + y + y + y − h, q = f / e.

Efectuând calculele manual, se obţin rezultatele:


h = 1 / 2, x = 1 / 6, y = 1 / 10 , e = 0, f = 0, q =?

Implementând aceste relaţii de calcul într-un program scris într-un limbaj oarecare şi executat
pe un calculator cu o aritmetică a virgulei mobile având baza β=2 , se obţin rezultatele:
e ≠ 0, f ≠ 0, q = valoare finită.

Explicaţia acestor rezultate constă în următoarele:


• numărul 2 / 3 = 0, (6) are un număr infinit de cifre în baza de numeraţie zece şi deci nu
va fi reprezentat exact;
• numărul 3 / 5 = 0,6 în baza de numeraţie zece, dar este un număr cu o infinitate de
cifre în baza de numeraţie doi, deci nici acest număr real nu va fi reprezentat exact:
0,6 zece = 0, (1001 ) doi .
Aceste erori de reprezentare se vor propaga în calculul valorilor e şi f rezultând valori de ordinul
epsilonului maşină.
Exemplul 1.12:
Fie ecuaţia: a ⋅ x 2 + b ⋅ x + c = 0 , cu a , b, c ∈ℜ. Soluţiile reale ale ecuaţiei se calculează,
de regulă, utilizând următoarele relaţii:

− b ± b2 − 4 ⋅ a ⋅ c
x 1, 2 = , b2 − 4 ⋅ a ⋅ c ≥ 0 .
2⋅a
14 1. Calculul în virgulă mobilă

Utilizând aceste relaţii de calcul, pentru determinarea soluţiilor ecuaţiei cu ajutorul unui
calculator având β=10 , t = 8 , L = −50 şi U = 50 , se obţin următoarele rezultate:
• pentru a =1 , b = −10 5 , c =1 : x 1 = 10 5 şi x 2 = 0 , în timp ce valorile adevărate
sunt x 1,a = 99999 .99999 şi x 2,a = 0.00001 .
• Diferenţele se datorează fenomenului de omitere catastrofală care apare la calculul
discriminantului: b 2 − 4 ⋅ a ⋅ c ≅ b 2 , pentru datele prezentate.
• pentru a = 6 ⋅10 30 , b = 5 ⋅ 10 30 , c = −4 ⋅10 30 , programul va fi abandonat cu emiterea
mesajului de “depăşire flotantă superioară”; această eroare se produce la calculul
discriminantului, atunci când b este ridicat la puterea a doua.
• pentru a =1 , b = −4 , c = 4 −10 −8 : x 1 = x 2 = 2 , rezultat care este eronat, datorită
fenomenului de neutralizare a termenilor apărut la calculul discriminantului.
Pentru a evita obţinerea de rezultate eronate, se adoptă următoarea soluţie:
(a) pentru a evita depăşirea flotantă superioară care s-ar putea produce la calculul lui b 2 ,
precum şi pentru evitarea fenomenului de omitere catastrofală, se rescrie discriminantul
sub forma:
δ = ∆ = ( b / 2) 2 − a ⋅ c .
Dacă | b / 2 |≥ c , se foloseşte relaţia de calcul:
δ =| b / 2 | ⋅ 1 − ( 2 ⋅ a / b) ⋅ ( 2 ⋅ c / b) ,
în care factorul 2 ⋅ c / b ≤ 1 .
Dacă | b / 2 |< c , se foloseşte relaţia de calcul:
δ = | c | ⋅ ( b / 2) ⋅ [b /( 2⋅ | c | )] − a ,
în care factorul b /( 2⋅ | c |) ≤1 .
(b) după calculul discriminantului, pentru evitarea neutralizării termenilor, se calculează mai
întâi rădăcina cu modulul mai mare, ţinând cont de semnul lui b:
x 1 = −(b / 2 + sign ( b) ⋅ δ) / a .

Rădăcina cu modulul mai mic se determină folosind relaţiile lui Viète între rădăcini şi
coeficienţi:
x 2 = c /( a ⋅ x 1 ) .

Procedând într-o astfel de manieră, în aceeaşi aritmetică a virgulei mobile, se obţin


rezultatele x 1 = 100000 şi x 2 = 0.00001 pentru primul set de coeficienţi prezentat. Pentru al
doilea set de coeficienţi, situaţia de eroare fatală nu mai apare, iar pentru ultimul set de
coeficienţi se obţin rezultatele x 1 = 2.0001 şi x 2 = 1.9999 .
Se recomandă abordarea exerciţiului E1.5, care se referă la un algoritm general pentru
rezolvarea cu acurateţe a ecuaţiei algebrice de ordinul al doilea, indiferent de natura (reală sau
complexă) a soluţiilor.
1.1 Aritmetica în virgulă mobilă 15

1.3 Natura problemelor de calcul şi caracterizarea algoritmilor

1.3.1 Natura problemelor de calcul

Se consideră o anumită problemă de calcul. Din punctul de vedere al matematicii reale,


problema lucrează cu datele exacte notate cu D. Se notează generic cu G ceea ce se doreşte a
calcula, implicând anumite relaţii matematice exacte. Aceasta poate fi scrisă sub forma unei
aplicaţii: D →G ( D) , cum este prezentat principial în Figura 1.6. Aşadar, G(D) reprezintă
soluţia matematică exactă, obţinută lucrând cu datele exacte D.
Se consideră D ∗ ca fiind datele D afectate de eroare (datele D perturbate). În acest caz,
soluţia exactă matematic a problemei de calcul corespunzătoare datelor perturbate D ∗ se
notează cu G ( D ∗) .
Definiţie:
Problema de calcul, G, se spune că este bine condiţionată dacă datele exacte ale problemei,
D, şi datele perturbate ale problemei, D ∗ , fiind apropiate într-un anumit sens, atunci şi
soluţia exactă matematic a problemei de calcul corespunzătoare datelor exacte, G(D), este
apropiată, într-un anumit sens de soluţia exactă matenatic a problemei de calcul
corespunzătoare datelor perturbate, G(D*). Altfel, problema de calcul se spune că este prost
(sau rău) condiţionată.

G
G(D)
D
≈ ≈
*
G(D )
D*

G
spaţiul datelor spaţiul soluţiilor

Fig. 1.6 Conceptul de problemă bine condiţionată: D ≅ D ∗ ⇒G ( D) ≅ G ( D ∗ )

Altfel spus, o problemă este bine condiţionată dacă mici perturbaţii în una sau toate datele
iniţiale ale problemei conduc la mici perturbaţii în datele de ieşire (rezultate sau soluţii).
Observaţie:
Pentru a caracteriza “apropierea” sau “îndepărtarea” dintre D şi D ∗ , respectiv G ( D) şi
G ( D ∗) , trebuie cunoscute două elemente: natura datelor D şi natura soluţiilor G ( D) .
Dacă D şi G ( D) aparţin mulţimii numerelor complexe, atunci se va folosi funcţia modul
pentru a aprecia diferenţele | D − D ∗ | şi, respectiv, | G (D) −G ( D ∗) | .
16 1. Calculul în virgulă mobilă

Dacă D şi G ( D) sunt elementele unui spaţiu liniar finit dimensional (vectori, matrice), se
vor folosi, corespunzător, norme vectoriale, respectiv matriciale.
În cele ce urmează, se notează generic erorile absolute ale mărimilor implicate cu:
e D =| D − D ∗ | şi e G =| G (D) − G (D ∗ ) | .

Se poate defini numărul de condiţie al problemei G ca fiind raportul dintre eroarea absolută
în soluţiile problemei de calcul şi eroarea absolută în datele de intrare ale problemei de calcul:
k (G ) = e G / e D .

Dacă acest număr de condiţie este egal cu 1 sau are valori apropiate de 1, se spune că
problema este bine condiţionată. Dacă numărul de condiţie este mare sau foarte mare, atunci
erorile în datele iniţiale sunt amplificate în soluţia problemei de calcul exactă matematic,
problema de calcul fiind prost condiţionată.
Exemplul 1.13:
Rezolvarea ecuaţiilor polinomiale este o problemă prost condiţionată. Fie Pn ( x ) un
polinom de gradul n:
Pn ( x ) = a 0 ⋅ x n + a 1 ⋅ x n −1 +  + a n −1 ⋅ x + a n ,

unde a i ∈ℜ, i =1,..., n; a 0 ≠ 0 sunt coeficienţii polinomului. Se doreşte determinarea


valorilor lui x pentru care Pn ( x ) = 0 .
În cele ce urmează, se va demonstra că mici variaţii în coeficienţii polinomului conduc la
variaţii mari în soluţiile calculate reprezentând rădăcinile polinomului.
Se consideră, în continuare, o altă problemă şi anume cea a calculului valorilor proprii ale
unei matrice reale pătratice, pe baza ecuaţiei caracteristice ataşate. Se consideră matricea A şi
varianta perturbată a acesteia, A p , de forma:

a 1 0  0 a 1 0  0
0 a 1   0 a 1  
   
A =    0 , A p =    0 .
   
  1   1

0   0 a
 nxn 
ε   0 a
 nxn

Ecuaţia caracteristică ataşată matricei A p este: p n (λ) = det( λ ⋅ I n − A p ) = 0 ,


unde I n este matricea unitate de ordinul n. Rezultă:

p n (λ) = (λ − a ) n − (−1) n ⋅ ε .

Ecuaţia p n (λ) = 0 conduce la (λ − a ) n = (−1) n ⋅ ε . Aşadar, o perturbaţie ε în datele de


intrare, conduce la o perturbaţie de n | ε | în soluţiile calculate.
Se consideră n =10 şi a =1 . Pentru cazul în care ε = 0 , rezultă valorile proprii
λi = a = 1, i = 1,  ,10 . Pentru cazul în care ε ≠0, ε =10 −10 , atunci valorile proprii sunt
−10
λi = a + 10 10 −10 = 1 + 0.1 = 1.1, i = 1,  ,10 . Rezultă: e D =10 şi e G =10 −1 . Dacă
1.1 Aritmetica în virgulă mobilă 17

ε = −10 −10 , atunci se obţin 10 valori proprii complex conjugate, dispuse în planul complex pe
un cerc cu centrul în punctul de coordonate (a,0) şi de rază egală cu 10 10 −10 = 0.1 . Cu
valorile numerice considerate, în cazurile particulare ale unei perturbaţii ε nenule, numărul de
condiţie al acestei probleme este:
k = e G / e D = 10 −1 / 10 −10 = 10 9 ,

deci eroarea din datele iniţiale ale problemei de calcul a fost amplificată de 10 9 ori în soluţiile
calculate.
În practică, datorită acestui fapt, nu se calculează valorile proprii ale unei matrice prin
aducerea matricei la forma canonică Jordan, utilizată în cadrul acestui exemplu, pentru că pot
apare perturbaţii cel puţin de genul celor prezentate.

1.3.2 Caracterizarea algoritmilor

Se consideră o problemă de calcul oarecare care lucrează cu setul de date exacte D. Soluţia
exactă matematic a acestei probleme este dată de “funcţia” G. Se consideră, în plus, datele
perturbate ale problemei, D ∗ .
La implementarea funcţiei G pe un calculator numeric, practic se lucrează cu un algoritm

G (a se vedea Figura 1.7).

G
G(D*)
D*
≈ ≈
*
G (D)
D

G*
spaţiul datelor spaţiul soluţiilor

Fig. 1.7 Conceptul de algoritm stabil numeric: D ≅ D ∗ ⇒G ∗ (D) ≅ G (D ∗ )

De exemplu, considerând că G este o problemă bine condiţionată şi că G ∗ implementează


exact soluţia G, totuşi G ( D) ≠G ∗( D) datorită aritmeticii în virgulă mobilă.
Natura algoritmului este teoretic caracterizată de următoarele două mărimi:
(a) soluţia matematică exactă a problemei de calcul corespunzătoare setului de date
perturbate, G ( D ∗) ;
(b) soluţia algoritmului G ∗ corespunzătoare setului de date exacte, G ∗( D) .
Definiţie:
Un algoritm G ∗ se numeşte stabil numeric, dacă datele exacte şi datele perturbate ale
18 1. Calculul în virgulă mobilă

problemei de calcul G fiind apropiate într-un anumit sens, atunci şi soluţia exactă matematic
corespunzătoare setului de date perturbate G(D*) este apropiată, într-un anumit sens, de
soluţia algoritmului corespunzătoare setului de date exacte G*(D). Altfel, algoritmul se spune
că este instabil din punct de vedere numeric.
Altfel spus, erorile din datele de intrare sunt micşorate de un algoritm stabil numeric, un
algoritm instabil numeric amplificându-le.
Observaţii:
(a) Nu se poate aştepta ca un algoritm stabil numeric să rezolve o problemă prost
condiţionată cu o precizie mai mare decât a datelor de intrare.
(b) Un algoritm instabil numeric furnizează, de regulă, rezultate eronate chiar pentru
probleme bine condiţionate.
Definiţie:

Un algoritm numeric se spune că este general dacă este aplicabil pentru un domeniu larg de
date de intrare.

Definiţie:

Un algoritm se spune că este sigur în funcţionare, dacă are prevăzut un mecanism care să
avertizeze atunci când erorile au crescut excesiv de mult.

Observaţie:
Un algoritm instabil numeric poate fi sigur în funcţionare, dacă este capabil să detecteze
instabilitatea numerică.
Concluzie:
Rolul calculului numeric (al analizei numerice) este de a analiza natura problemelor de
calcul şi de a realiza o proiectare optimă a algoritmilor. Dacă problema de calcul este prost
condiţionată, atunci aceasta se reformulează, echivalent, obţinând o problemă bine condiţionată.
Mai departe, pentru problema bine condiţionată rezultată, se proiectează un algoritm care să fie
stabil numeric, general şi sigur în funcţionare.
Exemplul 1.14:
Un exemplu de algoritm instabil numeric este cel folosit pentru calculul integralei definite:
1
I n = ∫ x n ⋅ e x −1 ⋅ dx ,
0

prin relaţia de recurenţă, exactă matematic:


I n = 1 − n ⋅ I n −1 , n = 2, 3,  ,
I1 = 1 / e, e = 2.71828182 ... .

Se consideră un calculator cu β=10 şi t = 6 . Vor rezulta următoarele valori:


1.1 Aritmetica în virgulă mobilă 19

Î1 ≅ 0.367879

Î 9 ≅ −0.068400 <0 !

dar, pentru I 9 , integrandul x 9 ⋅ e x −1 este pozitiv pentru x ∈(0,1) . Aşadar, s-a obţinut pentru
I 9 o valoare eronată. Singura eroare comisă a fost cea în estimarea lui 1 / e , care determină o
eroare în evaluarea lui I 1 egală cu e1 = 4.412 ×10 −7 . Pentru evaluarea lui I 2 , eroarea
comisă este e 2 ≅ ( −2) ⋅ e1 ; pentru I 3 eroarea comisă este e 3 ≅ (−3) ⋅ e 2 şi aşa mai departe
până la I 9 când se obţine o eroare e 9 = 9!⋅e1 = 0.1601 . Î 9 + e 9 = 0.0916 , ceea ce
reprezintă rezultatul exact cu patru cifre zecimale. Aceste rezultate arată că algoritmul utilizat
este instabil numeric.
Stabilizarea algoritmului se poate realiza rescriind relaţia de recurenţă sub forma:
I n −1 = (1 − I n ) / n = 1 / n − I n / n , n =  , 3, 2 .

Un majorant pentru I n este:


1 1
1
I n = ∫ x n ⋅ e x −1 ⋅ dx ≤ ∫ x n ⋅ dx = ,
0 0 n +1
deoarece | e x −1 |<1 pentru x ∈(0,1) . Aşadar, I n  n→∞ → 0 .
Pentru diverse valori ale lui n se obţin următoarele erori comise la calculul integralei
definite, considerând Î 20 = 0 :
n = 20 e 20 ≤ 1 / 21 ;
n = 19 e19 ≅ e 20 / 20 ;

n = 15 e15 < 4 ⋅ 10 −8 < β1− t = 10 −5 ;

n =9 Î 9 = 0.091612 - valoare cu şase zecimale exacte.

1.4 Exerciţii propuse


E1.1 Să se realizeze, într-un limbaj de programare, un program conţinând următoarea secvenţă
de instrucţiuni descrisă în limbajul pseudocod (Anexa B), în legătură cu Exemplul 1.11:
atribuie h ← 1/2
scrie ‘h = ’, h
atribuie x ← 2/3 - h
scrie ‘x = ’, x
atribuie y ← 3/5 - h
scrie ‘y = ’, y
atribuie e ← (x+x+x) - h
20 1. Calculul în virgulă mobilă

scrie ‘e = ’, e
atribuie f ← (y+y+y+y+y) - h
scrie ‘f = ’, f
atribuie q ← f/e
scrie ‘q = ’, q
Să se explice rezultatele obţinute.
E1.2 Să se realizeze, într-un limbaj de programare, un program conţinând următoarea secvenţă
de instrucţiuni descrisă în limbajul pseudocod:
atribuie h ← 1/10
atribuie x ← 0
pentru i = 1:10 execută
 atribuie x ← x + h

atribuie dif1 ← 1 - x
scrie ‘* test adunare:’
scrie ‘x = ’, x
scrie ‘dif1 = ’, dif1
atribuie y ← 10 * h
atribuie dif2 ← 1 - y
scrie ‘* test inmultire:’
scrie ‘y = ’, y
scrie ‘dif2 = ’, dif2
Să se explice rezultatele obţinute.
E1.3 Se considera problema evaluării, în diverse puncte x, a funcţiei e x . Calculul se bazeaza
pe dezvoltarea în serie Taylor, în jurul originii, a funcţiei şi oprirea unui anumit număr de
termeni, la precizia maşinii.
Să se realizeze, într-un limbaj de programare (de exemplu MATLAB), un program pentru
următorul algoritm, descris parţial în limbajul pseudocod:
atribuie IndRel ← 1
cât timp ( IndRel = 1 ) execută
 scrie ‘x = ’
 citeşte x
 atribuie sum ← 1
 atribuie trm ← 1
 atribuie n ← 0
 atribuie olds ← sum
 atribuie n ← n + 1
 atribuie trm ← trm * x/n
 atribuie sum ← sum + trm
 cât timp ( sum ~= olds ) execută
1.1 Aritmetica în virgulă mobilă 21

  atribuie olds ← sum


 | atribuie n ← n + 1
 | atribuie trm ← trm * x/n
 | atribuie sum ← sum + trm
 
 atribuie f ← sum
 scrie ‘nr.iter. = ’ n, ‘f = ’ f
 atribuie fx ← exp(x)
 scrie ‘fx = ’ fx
 scrie ‘1=reluare; 0=nu : ’
 citeşte IndRel

Observaţii:
1. ~= este notaţia MATLAB pentru operatorul relaţional “diferit de”.
2. exp este numele funcţiei MATLAB pentru calculul exponenţialei.
3. Programul se va rula pentru următoarele date de intrare:
x : 0.4; -0.4; 30.4; -30.4; 50.; -50.
Să se interpreteze rezultatele obţinute.
E1.4 Să se realizeze, într-un limbaj de programare (de exemplu MATLAB), un program pentru
următorul algoritm, descris parţial în limbajul pseudocod. Se rezolva problema de la
exerciţiul E1.3, eliminând de aceasta dată eroarea de metodă. Astfel, algoritmul descris în
exerciţiul anterior conduce la apariţia fenomenelor nedorite de neutralizare a termenilor şi
omitere catastrofală, pentru argumente x negative. Fenomenele menţionate conduc la
diferite rezultate eronate, în funcţie de mărimea argumentului negativ x.
atribuie e ← 2.718281828459
atribuie IndRel ← 1
cât timp ( IndRel = 1 ) execută
 scrie ‘x = ’
 citeşte x
 atribuie sum ← 1
 atribuie trm ← 1
 atribuie n ← 0
 atribuie fract ← abs( x – fix(x) )
 atribuie m ← fix( abs (x) )
 atribuie olds ← sum
 atribuie n ← n + 1
 atribuie trm ← trm * fract/n
 atribuie sum ← sum + trm
 cât timp ( sum ~= olds ) execută
  atribuie olds ← sum
 | atribuie n ← n + 1
22 1. Calculul în virgulă mobilă

 | atribuie trm ← trm * fract/n


 | atribuie sum ← sum + trm
 
 dacă ( x >= 0 ) atunci
  atribuie f ← sum * ( e^m )
 | altfel
 | atribuie f ← 1 / ( sum * (e^m ) )
 
 scrie ‘nr.iter. = ’ n, ‘f = ’ f
 atribuie fx ← exp(x)
 scrie ‘fx = ’ fx
 scrie ‘1=reluare; 0=nu : ’
 citeşte IndRel

Observaţii:
1. abs este numele funcţiei MATLAB pentru calculul valorii absolute.
2. fix este numele funcţiei MATLAB pentru calculul parţii întregi a unui număr real.
3. exp este numele funcţiei MATLAB pentru calculul exponenţialei.
4. ^ este notaţia MATLAB pentru operaţia de ridicare la putere.
5. ~= este notaţia MATLAB pentru operatorul relaţional “diferit de”.
6. >= este notaţia MATLAB pentru operatorul relaţional “mai mare sau egal”.
7. Să se analizeze şi explice diferenţele dintre algoritmii descrişi la exerciţiile E1.3 şi
E1.4.
8. Programul se va rula pentru datele de intrare precizate la exerciţiul E1.3. Să se
interpreteze rezultatele obţinute, comparând cu cele rezultate la exerciţiul anterior.
E1.5 Se consideră ecuaţia algebrică de gradul al -II-lea :
a ⋅ z 2 + b ⋅ z + c = 0; a , b, c ∈ℜ,
cu soluţiile generale:
z1 = z1r + j ⋅ z1i ;
z 2 = z 2r + j ⋅ z 2i , j 2 = −1

Aşa cum s-a prezentat în Exemplul 1.12, la rezolvarea numerică a acestui tip de ecuaţii
pot apare o serie de probleme care afectează, pe de o parte, precizia calculelor şi, pe de
altă parte, posibilitatea efectivă de calcul prin apariţia unor depăşiri în virgulă mobilă. În
aceste condiţii se propune un algoritm care încearcă să depăşească dificultăţile
menţionate.
Să se realizeze, într-un limbaj de programare (de exemplu MATLAB), un program pentru
următorul algoritm, descris parţial în limbajul pseudocod. Programul va conţine etapele
menţionate în continuare:
1. Introducere coeficienţi ecuaţie, în ordinea descrescătoare a puterilor lui z, în
variabilele a, b, c, respectiv.
2. Calcul soluţii după următorul algoritm:
1.1 Aritmetica în virgulă mobilă 23

dacă ( a = 0 ) atunci
 dacă ( b = 0 ) atunci
  atribuie z1r ← 0
 | atribuie z1i ← 0
 | atribuie z2r ← 0
 | atribuie z2i ← 0
 | altfel
 | atribuie z1r ← 0
 | atribuie z1i ← 0
 | atribuie z2r ← -c/b
 | atribuie z2i ← 0
 
| altfel
| dacă ( c = 0 ) atunci
  atribuie z1r ← 0
 | atribuie z1i ← 0
 | atribuie z2r ← - b/a
 | atribuie z2i ← 0
 | altfel
 | atribuie bp ← b/2
 | dacă ( abs( bp) >= abs(c) ) atunci
 |  atribuie e ← 1 – (a/bp) * (c/bp)
 | | atribuie d ← sqrt( abs( e)) * abs(bp)
 | | altfel
 | | atribuie e ← a
 | | dacă ( c < 0 ) atunci
 | |  atribuie e ← -a
 | | 
 | | atribuie e ← bp * ( bp/abs(c) ) - e
 | | atribuie d ← sqrt( abs( e)) * sqrt( abs(c) )
 | 
 | dacă ( e >= 0 ) atunci
 |  dacă ( bp >= 0 ) atunci
 | |  atribuie d ← -d
 | | 
 | | atribuie z1r ← ( - bp + d )/a
 | | atribuie z1i ← 0
 | | atribuie z2r ← 0
 | | dacă ( z1r ~= 0 ) atunci
 | |  atribuie z2r ← ( c/z1r )/a
 | | 
 | | atribuie z2i ← 0
 | | altfel
24 1. Calculul în virgulă mobilă

 | | atribuie z1r ← - bp/a


 | | atribuie z1i ← abs( d/a )
 | | atribuie z2r ← z1r
 | | atribuie z2i ← -z1i
 | 
 

scrie ‘z1 = ’ z1r, ‘ + ’, z1i, ‘ *j ’
scrie ‘z2 = ’ z2r, ‘ + ’, z2i, ‘ *j ’
3. Calcul rădăcini polinom de gradul doi, folosind funcţia MATLAB roots (a se vedea
observaţia 2 care urmează). Rezultatele se afişează.
4. Reluare program, dacă se doreşte, de la punctul 1.
Observaţii:
1. Se folosesc următoarele funcţii MATLAB: abs (calculul valorii absolute), sqrt
(calculul funcţiei radical), roots (calculul rădăcinilor unui polinom).
2. Funcţia MATLAB: roots
• Scop: calculul rădăcinilor unui polinom
• Apel: w = roots ( v );
• Parametri formali
i. Intrare: v – coeficienţii polinomului în ordinea descrescătoare a
puterilor. Dacă polinomul este de grad n:
v(1) ⋅ z n + v(2) ⋅ z n −1 +  + v( n ) ⋅ z + v( n +1) ,
atunci vectorul linie v conţine:
v = [ v(1) v(2) ... v(n) v(n+1) ]
ii. Ieşire: w – vector cu rădăcinile calculate.
3. Programul se va rula pentru urmatoarele date de intrare:
a b c
0. 0. 0.
0. 0. 1.
0. 2. 1.
3. 1. 0.
1. 5. 6.
1. 0. 1.
1. 1. 1.
1. -1.e+5 1.
6. 5. -4.
6.e+30 5.e+30 -4.e+30
1. -4. 4.
1. -4. 3.99999999
E1.6 Se consideră o funcţie de variabilă reală F : ℜ → ℜ , pentru care se cunosc valorile pe
nodurile (echidistante sau nu):
1.1 Aritmetica în virgulă mobilă 25

a = X1 < X2 < ....< Xn = b ; a, b - numere reale ;


Fi = F(Xi) ; i = 1,...,n.
Se doreşte reprezentarea grafică a punctelor (Xi, Fi), i=1,...,n într-un sistem rectangular
de axe, pe display-ul calculatorului. În afara de reprezentarea grafica, propriu-zisă, pe
display mai pot fi afişate o serie de informaţii numerice referitoare la mărimile
reprezentate. De asemenea se pot reprezenta două sau mai multe funcţii reale pe acelaşi
ecran.
Se consideră funcţia f : [ −1,1] →(0,1] cunoscută în analiza numerică sub denumirea
de "funcţia Runge", în legatură cu problema aproximării numerice a funcţiilor (tratată
într-un capitol următor):
1
f (x) = , −1 ≤ x ≤ 1.
1 + 25 ⋅ x 2
În cadrul acestui exerciţiu, se vor realiza mai multe reprezentări grafice ale funcţiei, pe
intervalul [-1,1], cu diverşi paşi de discretizare. Astfel, se consideră reţeaua de puncte
echidistante :
-1.= X1 < X2 <....< Xi <...< Xn = 1.
Xi = X1 + (i-1)*h; i = 1,2,…,n
unde h este pasul de discretizare: h = (Xn-X1)/(n-1).
Să se realizeze, într-un limbaj de programare (de exemplu MATLAB), un program pentru
reprezentarea grafică a funcţiei Runge, cu diferiţi paşi de discretizare. Valorile funcţiei
vor fi calculate cu ajutorul unei funcţii externe - utilizator, care va fi descrisă separat în
cele ce urmează (a se vedea observaţia 1). Programul va conţine etapele menţionate în
continuare:
1. Precizare interval de evaluare a valorilor funcţiei: [a,b], de exemplu:
a = -1. , b = 1.
2. Introducere numere de puncte, în variabilele np1 şi, respectiv, np2, (np1 < np2), în
care vor avea loc evaluările funcţiei.
3. Calcul paşi de discretizare: h1 = (b-a)/(np1-1); h2 = (b-a)/(np2-1).
4. Generare seturi de puncte pentru reprezentarea grafică:
• abscise în vectorul x1, conţinând elemente cu valori de la a la b, cu pasul de
creştere h1;
• abscise în vectorul x2, conţinând elemente cu valori de la a la b, cu pasul de
creştere h2;
• ordonate în vectorul y1, conţinând valorile funcţiei Runge, evaluată în punctele
din vectorul x1 (descriere pseudocod):
execută y1 = FRUNGE (x1);
• ordonate în vectorul y2, conţinând valorile funcţiei Runge, evaluată în punctele
din vectorul x2 (descriere pseudocod):
execută y2 = FRUNGE (x2);
5. Reprezentare cu grafice suprapuse: se reprezintă perechile de puncte (x1,y1) şi,
respectiv, (x2,y2), în acelaşi grafic.
26 1. Calculul în virgulă mobilă

6. Reluare program cu alte valori pentru numerele de puncte de discretizare, daca se


doreşte, de la punctul 2.
7. Reluare generală program, daca se doreşte, de la punctul 1.
Observaţii:
1. Programul apelează funcţia utilizator FRUNGE. O modalitate de descriere a acesteia
în limbajul MATLAB (creând un fişier utilizator cu numele ’FRUNGE.m’), este:
function y = FRUNGE ( x )
%
n = length(x);
y = ones(1,n) ./ ( 1 + 25 * x .^2 );
%
unde length reprezintă funcţia pentru determinarea numărului de elemente ale unei
matrice, iar ones este funcţia pentru generarea unei matrice cu elemente egale cu 1,
de dimensiuni indicate (număr linii, număr coloane). Apelul funcţiei, în limbajul
MATLAB, este:
y = FRUNGE ( x );
2. Programul se va rula pentru următoarele date de intrare:
• np1 = 5 np2 = 100 ;
• np1 = 6 np2 = 100 .
3. Programul pune în evidenţă:
• evaluarea/reprezentarea neadecvată a funcţiilor, dacă pasul de
discretizare/evaluare este ales prea mare;
• aproximarea liniară a funcţiilor, cunoscând un şir de valori (x,y), într-un interval
dat (reprezentarea grafică în np1 puncte).

1.5 Probleme propuse


P1.1 Se consideră un număr întreg Z cu 12 cifre în baza de numeraţie zece,
Z = 3141592653 58 . În baza de numeraţie doi, acest număr are 38 de cifre binare. Se
consideră un calculator pentru care numerele sunt reprezentate conform standardului
IEEE. Acest număr se poate reprezenta exact, aproximativ sau nu se poate reprezenta ca:
(a) întreg, utilizând 16 poziţii binare?
(b) întreg, utilizând 32 poziţii binare?
(c) real în simplă precizie?
(d) real în dublă precizie?
Justificaţi răspunsul.
P1.2 Se consideră următoarele relaţii de calcul:
t = 0.1
n = 1 / 10
e = n / 10 − n * t
1.1 Aritmetica în virgulă mobilă 27

Să se implementeze aceste expresii într-un limbaj de programare, cu afişarea valorilor


atribuite variabilelor din membrul stâng, şi să se explice rezultatele obţinute.
P1.3 Se consideră următorul algoritm descris în limbaj pseudocod:
atribuie eps ← 1
cât timp ( eps > 0 ) execută
 scrie ‘eps=’, eps
 atribuie eps ← eps/2

Să se precizeze ce semnificaţie are ultima valoare tipărită? Să se verifice răspunsul dat
prin implementarea algoritmului într-un limbaj de programare.
P1.4 Să se descrie, în limbaj pseudocod, algoritmul pentru determinarea epsilonului maşină
pentru operaţia de scădere. Să se implementeze, într-un limbaj de programare, algoritmii
pentru calcul epsilonului maşină pentru operaţiile de adunare şi scădere. Să se compare
rezultatele obţinute.
P1.5 Se consideră următorul algoritm descris în limbaj pseudocod:
atribuie eps ← 1
atribuie k_bit ← 0
atribuie eps1 ← eps+1
cât timp [( eps 1 >1 ) şi ( eps 1 −eps =1 )] execută
 atribuie eps ← eps/2
 atribuie k_bit ← k _ bit + 1
 atribuie eps1 ← eps +1

dacă ( eps 1 −eps =1 ) atunci
 atribuie eps ← 2 ∗eps

scrie ‘eps = ’, eps
scrie ‘k_bit = ’, k_bit
Să se precizeze ce semnificaţie au valorile tipărite pentru variabilele eps şi k_bit. Să se
verifice răspunsul dat prin implementarea algoritmului dat într-un limbaj de programare.
P1.6 Calculul aproximativ al valorii unei funcţii, de exemplu e x , se bazează pe evaluarea
unor serii infinite, cu termeni descrescători în modul. Algoritmul general folosit reflectă
precizia maşinii de calcul, calculele oprindu-se în momentul în care un termen de sumat
nu mai are influenţă asupra sumei parţiale, calculate la un anumit moment dat. Descrierea
principială, în limbaj pseudocod, a unui astfel de algoritm este următoarea:
scrie ‘x =’
citeşte x
atribuie sum _ n ← 1
atribuie sum _ v ← 0
28 1. Calculul în virgulă mobilă

atribuie k ← 0
cât timp ( s u m_ v ≠ s u m_ n ) execută
 atribuie k ← k + 1
 * calculează term ca funcţie de k şi x
 atribuie s u m_ v ← s u m_ n
 atribuie sum_n ←sum_v + term

atribuie f ← sum _ n
scrie ‘funcţie calculată (x) = ‘, f
În descrierea anterioară, f reprezintă valoarea aproximativă a expresiei de evaluat.
(a) Folosind algoritmul general, să se descrie, în limbaj pseudocod, algoritmul pentru
calculul seriei infinite divergente:
S =1 + 1/ 2 + 1/ 3 + 1/ 4 +  + 1/ n +  .
(b) Să se implementeze într-un limbaj de programare algoritmul obţinut la punctul (a) şi
să se execute programul obţinut.
(c) Să se explice de ce seria dată nu este divergentă atunci când aceasta este evaluată cu
un calculator numeric.
(d) Să se completeze programul obţinut la punctul (b), calculând seria de la punctul (a)
prin evaluarea de la dreapta la stânga (pornind de la cel mai mic termen semnificativ
pentru sumă).
(e) Să se compare rezultatele de la punctele (b) şi (d). Să se explice diferenţele, dacă
acestea există.
P1.7 Se consideră calculul funcţiei sin(x) utilizând exprimarea acesteia drept o serie (infinită)
de puteri:
x3 x5 x7
sin( x ) = x − + − + ... ,
3! 5! 7!
şi următorul algoritm descris în limbajul pseudocod:
scrie ‘x =’
citeşte x
atribuie sinx ← 0
atribuie term ← x
atribuie k ← 1
cât timp ( sinx + term ~= sinx ) execută
 atribuie sinx ← sinx + term
 atribuie term ← - (x^2) / ( (k+1)*(k+2) ) * term
 atribuie k ← k + 2

atribuie f ← sinx
scrie ‘funcţie calculată sin(x) = ‘, f
1.1 Aritmetica în virgulă mobilă 29

Să se explice motivul pentru care ciclul cu test iniţial (cât timp - execută) se parcurge de
un număr finit de ori.
Să se răspundă la urmâtoarele întrebări, variabila x luând succesiv valorile
π / 2, 11 ⋅ π / 2, 21 ⋅ π / 2, 31 ⋅ π / 2 , implementând algoritmul într-un limbaj de
programare:
(a) Cât de precis este rezultatul calculat?
(b) Care este numărul de termeni folosiţi din seria de puteri?
(c) Care este cel mai mare termen folosit din seria de puteri?
Implementând algoritmul prezentat în mediul de programare MATLAB,, să se compare
rezultatele astfel obţinute cu cele furnizate prin utilizarea funcţiei MATLAB sin,
corespunzătoare valorilor precizate pentru argumentul x. Să se explice diferenţele
obţinute şi, dacă este cazul, să se corecteze algoritmul astfel încât diferenţele între cele
două variante (funcţia MATLAB sin şi algoritmul corectat) să fie cât mai mici posibile.

S-ar putea să vă placă și