DUzun's Web
Programare, proiecte personale, divertisment

duzun.teologie.net
 Home >> Programare >> Numere reale  
arr_d Navigator
arr_d File Browser

Floating point

Reprezentarea numerelor reale în formatul mașinii
Standardul IEEE 754 floating-point (virgula plutitoare [i])

Autor:
Uzun Dumitru

Introducere

Dat fiind faptul că în calculatoare se folosește punctul, nu virgula, la notarea fracțiilor zecimale, voi folosi notația cu punct.

Există mai multe metode de reprezentare a numerelor reale în calculatoare. Un mod de reprezentare este plasarea punctului undeva pe la mijlocul fracției, ceea ce este echivalent cu rezervarea a doi întregi – unul pentru partea întreagă și altul pentru partea fracționară a numărului. Astfel, având un număr de patru cifre (două pentru partea întreagă și două pentru cea fracționară), fracția 1/100 ar fi reprezentată ca 00.01, iar 329/10 ca 32.90

O altă modalitate de reprezentare a numerelor reale este folosirea numerelor raționale, adică doi întregi reprezintă numărătorul și numitorul.

Reprezentarea cea mai des folosită este cea cu virgula plutitoare (floating-point). Această reprezentare se aseamănă mult cu notația științifică a numerelor. De exemplu, 148.554 poate fi reprezentat ca 1.48554 × 102, sau 0.148554 × 103. Astfel, ceea ce trebuie să reprezentăm este un număr întreg pentru mantisă[ii] și un număr întreg pentru exponent, baza de numerație[iii] și caracteristica[iv] fiind implicite. Cu alte cuvinte, mantisa reprezintă precizia (rezoluția) numărului, iar exponentul – valoarea (domeniul de lucru: fracții, unități, sute, mii, ș.a.m.d).

Virgula plutitoare rezolvă unele probleme de reprezentare. Virgula fixă are o fereastră fixă de reprezentare, ceea ce împiedică de a reprezenta numere foarte mari sau foarte mici. De asemenea, virgula fixă tinde să piardă din precizie când două numere mari sunt împărțite.

Pe de altă parte, virgula plutitoare impune un fel de „fereastră alunecătoare” a preciziei, potrivită proporțiilor numărului, ceea ce-i permite să reprezinte numere de la 10x până la 10-x cu ușurință.

Mai departe vor fi studiate doar numerele în formatul floating-point.

 

Forma de stocare în memorie:

După cum s-a menționat mai sus, pentru numerele floating-point este nevoie de reprezentat doar mantisa și exponentul numărului în notația științifică, însă mantisa poate fi număr pozitiv sau negativ. Deci mai este nevoie de un bit pentru semnul numărului.

Să facem câteva notații:
nr  – numărul real
s    – semnul
c    – caracteristica
m   – mantisa
e    – exponentul
d    – deplasarea

Cu aceste notații orice număr real poate fi scris ca nr = (-1)s × c.m × 10e  (în baza 2).

Figura ce urmează arată formatul intern[v] al numerelor cu virgulă plutitoare:

Semn (s)

Exponent (d + e)

Mantisă (m)

0 sau 1 – un bit

deplasarea + exponentul real

normalizată sau denormalizată

Semnul:

Bitul de semn[vi] doar indică semnul, nimic mai mult: 0 pentru număr pozitiv și 1 pentru număr negativ.

Exponentul:

Spre deosebire de reprezentarea numerelor întregi negative[vii] în formatul mașinii, exponentul în formatul floating-point folosește deplasarea[viii] pentru a putea reprezenta valorinegative. Deplasarea este o constantă care se calculează în funcție de mărimea câmpului exponentului, și anume este jumate din valoarea maximă care poate fi reprezentată de acest câmp. De ex., dacă câmpul exponentului are capacitatea de reprezentare pe intervalul [0..255], când adăugăm deplasarea (d = 127), e ia valori din [‑127..128], astfel (e + d) numai bine se încadrează în câmpul exponentului și de aici putem reprezenta exponentul negativ (e < 0).

Mantisa:

Mantisa poate fi normalizată sau denormalizată[ix]. Dacă exponentul este egal cu zero (e + d = 0), mantisa este denormalizată și caracteristica se consideră nulă (c = 0). Iar dacă exponentul este diferit de zero (e + d <> 0), mantisa este normalizată, iar caracteristica se consideră 1 (c = 1)[x]. Altfel spus, când mantisa este normalizată, ea împrumută o cifră caracteristicii (1.nnn), iar când este denormalizată, ea reprezintă toate cifrele singură (0.1nnn), iar caracteristica nu reprezintă nici o cifră. De ex., numărul 1.00101001 se va scrie în forma normalizată 1.00101001 × 100, iar în cea denormalizată ca 0.100101001 × 101.

Observați că 101.110 nu poate fi reprezentat în forma denormalizată, deoarece câmpul exponentului nu poate fi nul în acest caz (e + d <> 0).

Având în vedere că caracteristica ia doar valorile 0 sau 1[xi], și acestea în funcție de forma numărului (denormalizat sau normalizat), nu este nevoie să rezervăm un câmp special pentru caracteristică.

Forma normală a mantisei este cea normalizată, iar cea denormalizată este rezervată pentru a putea reprezenta valorile speciale.

Sumar:

1.      Bitul de semn este 0 pentru numere pozitive și 1 pentru cele negative.

2.      Baza exponentului este 2, implicit.

3.      Câmpul exponentului conține valoarea exponentului plus deplasare.

4.      Deplasarea este constantă pentru fiecare format de reprezentare și este jumate din valoarea maximă posibilă a câmpului exponentului.

5.      Caracteristica totdeauna se consideră 1 pentru forma normalizată și 0 pentru  cea denormalizată, implicit.

Capacitatea numerelor Floating-Point

Să examinăm puțin formatul float[xii]. Observați că în esență luăm un număr de 32 biți și manipulăm câmpurile lui pentru a acoperi un domeniu cât mai mare de valori. Ceva totuși trebuie să se piardă, și anume se pierde precizia. De exemplu, întregii obișnuiți de 32 biți, cu toată precizia centrată în jurul lui zero, pot cu exactitate să stocheze întregi cu o rezoluție de 32 biți. Floating-point, pe de altă parte, nu poate reprezenta această rezoluție cu doar 24 biți ai săi. Dar totuși aproximează această valoare, tăind numărul din partea de jos. De exemplu:

  11110000 11001100 10101010 00001111 = // întreg de 32 biți
= +1.1110000 11001100 10101010 x 231    = // float de 32 biți
=  11110000 11001100 10101010 00000000   // valoarea corespunzătoare

Aceasta aproximează valoarea de 32 biți, dar nu dă o reprezentare exactă. Pe de altă parte, în afară de capacitatea de a reprezenta componentele fracționare (de care întregii sunt lipsiți), valorile floating-point pot reprezenta numere în jurul lui 2127, în comparație cu valoarea maximă a întregilor de 32 biți de aproximativ 232.

Sunt cinci valori distincte pe care numerele floating-point de 32 biți nu le pot reprezenta[xiii]:

1.            Numerele negative mai mici ca -(2-2-23) × 2127                            (negative overflow)

2.            Numerele negative mai mari ca -2-149                                               (negative underflow)

3.            Zero

4.            Numerele pozitive mai mici ca 2-149                                                  (positive underflow)

5.            Numerele pozitive mai mari ca (2-2-23) × 2127                              (positive overflow)

Overflow (supraîncărcarea) înseamnă că valorile au crescut prea mari pentru reprezentare, foarte asemănător cum poți supraîncărca întregii.

Underflow (subîncărcarea) e o problemă mai puțin importantă, deoarece ea denotă doar o pierdere a preciziei, care este garantată să fie aproape aproximată cu zero.

Valori Speciale

IEEE rezervă valorile exponentului cu toți biții 0 și toți biții 1 pentru a indica valorile speciale în schema floating-point.

Zero

După cum s-a menționat mai sus, zero nu este reprezentabil direct în forma simplă, datorită asumării că caracteristica normalizată este totdeauna 1 (vom avea nevoie să specificăm o caracteristică nulă pentru a produce valoarea zero). Zero este o valoare specială însemnată de câmpul exponentului umplut cu zero și câmpul mantisei umplut cu zero. Observați că +–0 și -0 sunt valori distincte, cu toate că ele ambele se compară ca egale.

Infinit

Valorile +infinit și -–infinit sunt indicate de un exponent cu toți biții 1 și o mantisă cu toți biții 0. Bitul de semn distinge infinitul pozitiv și negativ. Capacitatea reprezentării infinitului ca o valoare specială este utilă, pentru că permite operațiilor să continue după situații de overflow. Operațiile cu valorile infinite sunt bine definite în standardul IEEE floating-point.

Not A Number (Nu e Număr)

Valoarea NaN (Not a Number) este folosită pentru a indica o valoare care nu reprezintă un număr adevărat. NaN-urile sunt reprezentate de o segvență specială de biți cu câmpul exponentului umplut cu 1 și o mantisă nenulă. Sunt două categorii de NaN: QNaN (Quiet NaN – tăcut) și SNaN (Signalling NaN – alarmant).

QNaN este un NaN cu bitul semnificativ al mantisei setat. QNaN-urile se propagă liber prin cele mai multe operații aritmetice. Aceste valori rezultă din operație atunci când rezultatul nu este definit matematic.

Un SNaN este un NaN cu bitul semnificativ al mantisei gol. Se utilizează pentru a semnala o excepție când se folosește în operații. SNaN-urile pot fi comode pentru a fi atribuite variabilelor neinițializate, cu scopul de a capta utilizarea prematură.

Semantic, QNaN-urile denotă operații nedeterminate, în timp ce SNaN-urile denotă operații invalide.

Sumar

Tabelul ce urmează acoperă toate valorile posibile pe care le poate lua un număr în formatul floating-point, indicând pentru fiecare caz configurația câmpurilor de biți:

Valorile Float

Semn

Exponent (e)

Mantisa (m)

Valoare

0

00..00

00..00

+0

0

00..00

00..01
. . .
11..11

Real Pozitiv Denormalizat
0.m × 2(-d+1)

0

00..01
. . .
11..10

XX..XX

Real Pozitiv Normalizat
1.m × 2(e-d)

0

11..11

00..00

+Infinit

0

11..11

00..01
. . .
01..11

SNaN

0

11..11

10..00
. . .
11..11

QNaN

1

00..00

00..00

-0

1

00..00

00..01
. . .
11..11

Real Negativ Denormalizat
-0.m × 2(-d+1)

1

00..01
. . .
11..10

XX..XX

Real Negativ Normalizat
-1.m× 2(e-d)

1

11..11

00..00

-Infinit

1

11..11

00..01
. . .
01..11

SNaN

1

11..11

10..00
. . .
11.11

QNaN

Spre deosebire de notațiile utilizate anterior, aici e reprezintă valoarea câmpului exponentului, adică exponentul real plus deplasare (e := e + d).

 

Anexă

1.     Reprezentarea în formatul mașinii a numerelor floating-point[xiv]:

Semn

Exponent

Caracteristică

Mantisă

Float

1 [31]

8 [30-23]

–

23 [22-00]

Double

1 [63]

11 [62-52]

–

52 [51-00]

Long Double[xv]

1 [79]

15 [78-64]

1 [63]

63 [62-00]

2.     Deplasări:

 

Zecimal

Binar

Hexazecimal

Float (8 biți)

127

0111 1111

7F

Double (11 biți)

1023

011 1111 1111

3FF

Long Double (15 biți)

16383

011 1111 1111 1111

3FFF

3.     Domeniul de valori:

Format [biți]

Denormalizate

Normalizate

Aproximația zecimală

Float [32]

2-149 la (1-2-23)×2-126

2-126 la (2-2-23)×2127

~10-44.85 la ~1038.53

Double [64]

2-1074 la (1-2-52)×2-1022

2-1022 la (2-2-52)×21023

~10-323.3 la ~10308.3

Long Double [80]

2-16444 la (1-2-62)×2-16382

2-16382 la (2-2-62)×216383

~10-4950.14 la ~104931.69

Odată ce semnul numerelor floating-point este dat de bitul special din față, domeniul negativ al acestor numere se obține prin negarea valorilor de mai sus.

4.     Operații Speciale:

Operațiile cu numerele speciale sunt bine definite de către IEEE. În cel mai rău caz, orice operație cu un NaN dă un rezultat NaN. Alte operații sunt după cum urmează:

Operația

Rezultatul

n ÷ ±Infinit

0

±Infinit × ±Infinit

±Infinit

±nonzero ÷ 0

±Infinit

Infinit + Infinit

Infinit

±0 ÷ ±0

NaN

Infinit - Infinit

NaN

±Infinit ÷ ±Infinit

NaN

±Infinit × 0

NaN

 

Cuprins:


Introducere
Forma de stocare în memorie
Capacitatea numerelor Floating-Point
Valori Speciale
Sumar
Anexă

 


[i] Floating-point se traduce „punct plutitor”. În calculatoare pentru separarea părți fracționare în număr se folosește punctul, nu virgula, deoarece în multe țări, inclusiv SUA, se utilizează anume această notație.

[ii] Partea fracționară a numărului.

[iii] În formatul mașinii baza de numerație este 2. Iar 10 în baza doi este 2 în baza zece (102 = 210), de aceea nu voi specifica explicit baza numerelor în exemple, ci voi considera că 10 este în baza 2.

[iv] Partea întreagă a numărului.

[v] Vezi anexa – 1

[vi] if (nr < 0)  then s = 1 else if (nr > 0) then s = 0

[vii] –|nr| = not |nr| 1.

De ex., nr. -2 pe 4 biți se reprezintă astfel: -0010 = not 0010 1 = 1101 1 = 1110. Astfel -2 2 =0 este același lucru cu 1110 0010 = 0000 și overflow.

[viii] d = max{e} div 2. Vezi anexa – 2

[ix] Normalizată:    (-1)s × 1.m × 10e
  Denormalizată: (-1)s × 0.m × 10e

[x] if (d e = 0) then c = 0  else c = 1

[xi] Caracteristica nu poate avea alte valori, având la dispoziție doar o cifră binară. Deci este 1 când reprezintă o cifră și 0 când nu reprezintă nici o cifră.

[xii] Vezi anexa – 3

[xiii] Se are în vedere forma normalizată a numărului, care este forma standard.

[xiv] În parantezele parate se indică biții pe care se reprezintă numărul

[xv] Acest format este un caz particular, deoarece el se folosește de către coprocesor pentru efectuarea operațiilor cu numerele reale și de acea caracteristica se reprezintă explicit (un bit).

News

arr_d Limba / Language
Loading Google Translate Element. . .


  Distribuie


Music


arr_r Login
arr_d Email

Temporar suspendat ;-(

arr_d Info vizite

free counters