Reprezentarea internă a datelor în virgulă mobilă

În general, reprezentarea internă a numerelor în virgulă mobilă depinde de tipul calculatorului și de limbajul de programare utilizat. Acesta impune lungimea zonei de memorie alocatepentru un număr, împărțirea acesteia între mantisă și coeficient, convenția de semn adoptată, etc.
 
În matematică, un număr real poate fi reprezentat în diferite forme: 
    - ca o fracție zecimală, de exemplu 723,5784;
    - ca o fracție ordinară, de exemplu 172/17;
    - ca un număr irațional, de exemplu rădăcina patrată a lui 2;
    - ca un număr fracționar într-un alt sistem de numerație; de exemplu, următorul număr în sistemul de numerație binar: 1001,1101000101.

În cazul fracțiilor zecimale, lungimea numărului (numarul de cifre pe care acesta le conține) poate fi în principiu oricât de mare, chiar și infinită. Nu există restricții privind lungimea numărului.

În memoria internă a calculatorului, datele se codifică prin numere binare de lungime finită. Este deci clar că nu orice fel de numere reale pot fi reprezentate în calculator. 

Convenția de reprezentare a numerelor în virgulă mobilă are la bază așa numita "notație științifică" a numerelor reale, sub forma m.10n, în care m este un numar întreg sau fracționar numit mantisă (coeficient), iar n este un numar întreg numit exponent. De exemplu, numarul 0,000000280735 poate fi scris în notația științifică sub forma 0,280735.10-6, iar numărul -14567823496,174 poate fi scris sub forma -0,14567823496174.1011. Se observă cu usurință că valoarea exponentului n indică cu câte cifre trebuie sa fie deplasată virgula mantisei, pentru a o plasa pe pozitia ei normala, iar semnul exponentului arată sensul acestei deplasări. De exemplu, exponentul -6 arata că virgula trebuie deplasată cu 6 cifre spre stânga. De aici provine denumirea de reprezentare în "virgulă mobilă" sau "virgulă flotantă".

Pentru reprezentarea numerelor reale în memoria internă a calculatorului, s-a adoptat convenția de reprezentare în virgulă mobilă (virgula flotantă). În consecință, fiecare număr real este reprezentat prin doua numere binare, mantisa și exponentul. Mantisa este un numar binar fracționar cu semn, cu partea întreagă nulă, iar exponentul este un numar binar întreg cu semn. Abordarea este asemănătoare cu cea de mai sus, numai că se folosește sistemul de numerație binar.

Pentru întregul număr real se rezervă în memorie o zonă de lungime fixă și finită (de exemplu patru sau 8 octeti). Această zonă se împarte, la rândul ei, în două subzone: pentru coeficient și pentru exponent. Aceasta înseamnă că atât mantisa, cât și exponentul au lungimi finite, care depind de lungimea zonei de memorie alocate.

Întrucât se folosește sistemul de numerație binar, numărul real se va exprima sub forma m.2n, în care m este mantisa, iar n este exponentul. În memoria calculatorului se înregistrează efectiv numai m și n, baza 2 fiind implicită.

În cazul limbajului Java, reprezentarea internă a datelor in virgulă mobilă este unică pentru toate tipurile de calculatoare, deoarece nu se referă la un calculator concret, ci la mașina virtuală Java. Aceasta reprezentare este cea specificată prin standardul ANSI/IEEE 754-1985.
ANSI - American National Standards Institute - Institutul National de Standardizare al SUA;
IEEE - Institute of Electrical & Electronics Engineers - Organizatia (Institutul) Inginerilor Electrotehnicieni și Electronisti.

Datele de tip float sunt reprezentate intern pe 4 octeți (32 biți) alocați astfel: unul pentru semnul mantisei, 24 pentru modulul mantisei și 8 pentru exponent.

Datele de tip double sunt reprezentate intern pe 8 octeți (64 biți), alocați astfel: unul pentru semnul mantisei, 52 pentru modulul mantisei și 11 pentru exponent.

Atât la tipul float, cât și la tipul double au fost rezervate câte trei valori binare speciale, care reprezinta valorile Infinity, -Infinity si NaN.

Datorită faptului că semnul este reprezentat separat de modulul mantisei, a apărut situația că există două zerouri în virgulă mobilă: +0.0 si -0.0. Se consideră că +0.0 este egal cu -0.0, dar, de exemplu, operația 1.0/(+0.0) dă rezultatul plus infinit (Infinity),  în timp ce 1.0/(-0.0) dă rezultatul minus infinit (-Infinity).

Lungimea mantisei condiționează precizia numărului. Astfel, precizia datelor de tip float este de 7 cifre semnificative, iar pentru tipul double de 17 cifre semnificative. Numărul de cifre binare rezervate pentru exponent condiționează valoarea maximă a acestuia.
 
Remarcăm că numărul de valori pentru un anumit tip de date este întotdeauna finit și depinde numai de lungimea reprezentării interne, nu și de tipul de date în sine. De exemplu, pe o lungime de 32 biți (4 octeți) se reprezintă 232 valori, indiferent că este vorba de tipul int sau float. Deosebirea între cele două tipuri constă în modul de interpretare a șirului de biți respectiv, ceeace afectează și modul în care se fac operațiile de calcul cu numărul pe care acești biți il reprezintă.

La o privire neatentă, s-ar putea considera că mulțimea de valori pentru un anumit tip de date reale este un anumit interval. De exemplu, pentru tipul float în Java s-ar putea considera ca mulțimea de valori conține toate numerele reale din intervalul [-3.402347e+38f,  3.402347e+38f]. În realitate, ea conține numai 232-3 valori discrete din acest interval, la care se adaugă cele trei valori speciale, Infinity, -Infinity și NaN. În mod similar, mulțimea valorilor tipului de date double contine numai 264-3 valori discrete în intervalul [-1.7976931348623157e+308, 1.7976931348623157e308] plus cele trei valori speciale menționate, adică tot atâtea valori, cât are și tipul long.

Având în vedere comentariul de mai sus, este clar dece denumirea de tipuri de date în virgulă mobilă este mai corectă decât cea de tipuri de date reale. De fapt, valorile în virgulă mobilă sunt numere reale aproximative. O astfel de valoare este aproximarea tuturor numerelor reale dintr-un anumit interval. De exemplu, valoarea de tip float 307.1206f este aproximarea numerelor reale din intervalul [307.12055, 30712065]. Eroarea relativă a aproximării este 2-24 pentru numerele de tip float și 2-52 pentru cele de tip double, corespunzător lungimii mantisei.



© Copyright 2000 - Severin BUMBARU, Universitatea "Dunărea de Jos" din Galați