Cum sunt stocate numerele negative în memoria computerului? Ce trebuie să știți despre aritmetica în virgulă mobilă

Reprezentarea numerelor într-un computer

Numerele întregi sunt cele mai simple date numerice cu care operează un computer. Numerele întregi sunt stocate într-un computer în format punct fix. În acest caz, fiecare cifră a celulei de memorie corespunde întotdeauna aceleiași cifre a numărului, iar „virgula” este situată în dreapta după cifra cea mai puțin semnificativă.

Pentru a stoca întregul număr negativ unei celule de memorie i se alocă 1 octet (8 biți), adică intervalul de numere care pot fi stocate în memorie cu acces aleatorîn format de numere întregi nenegative, de la 0 la 255 (256 în total). Numărul minim 0 corespunde cu opt zerouri, iar maximul 255 corespunde cu opt unități (255 10 = 11111111 2).

Pentru a reprezenta un întreg cu semn, bitul cel mai semnificativ (stânga) este alocat semnului numărului, biții rămași sunt alocați numărului însuși. Dacă numărul este pozitiv, atunci 0 este plasat în bitul de semn, dacă este negativ - 1. De exemplu, într-un octet puteți reprezenta numere semnate de la -128 la 127.

Pentru reprezentare pe calculator numerele întregi folosesc de obicei unul, doi sau patru octeți, ceea ce înseamnă că celula de memorie va avea opt, șaisprezece sau, respectiv, treizeci și doi de biți.

Reprezentarea unui număr în forma obișnuită „semn” - „magnitudine”, în care cea mai semnificativă cifră a celulei este alocată semnului, iar restul - pentru înregistrarea numărului în sistem binar, numit codul direct al unui număr binar.

De exemplu, cod direct numere binare 1001 și -1001 pentru o celulă de 8 biți sunt 0 0001001 și, respectiv, 1 0001001.

Numerele pozitive sunt întotdeauna reprezentate într-un computer folosind cod direct. Codul direct al numărului coincide complet cu înregistrarea numărului în sine în celula mașinii.

Codul direct al unui număr negativ diferă de codul direct al numărului pozitiv corespunzător numai în conținutul bitului de semn.
Dar numerele întregi negative nu sunt reprezentate într-un computer folosind cod direct; ele sunt reprezentate folosind cod suplimentar.

Codul complementului a doi al unui număr pozitiv este egal cu codul direct al numărului respectiv.

Codul complementului a doi al unui număr negativ m este 2 n -|m|, unde n este numărul de cifre din celulă.

Codul complementar este folosit pentru a face operațiile aritmetice mai ușor de efectuat. Dacă Mașină de calcul a lucrat cu coduri directe de numere pozitive și negative, apoi la efectuarea operațiilor aritmetice ar fi necesar să se efectueze o serie acțiuni suplimentare. De exemplu, atunci când adăugați, ar trebui să verificați semnele ambilor operanzi și să determinați semnul rezultatului. Dacă semnele sunt aceleași, atunci se calculează suma operanzilor și i se atribuie același semn. Dacă semnele sunt diferite, atunci de cel mai mare valoare absolută numărul mai mic este scăzut și rezultatului i se atribuie un semn Mai mult. Adică, cu această reprezentare a numerelor (sub formă doar de cod direct), operația de adunare este implementată printr-un algoritm destul de complex. Dacă numerele negative sunt reprezentate sub forma unui cod suplimentar, atunci operația de adunare, inclusiv a celor de diferite semne, se reduce la adăugarea lor pe biți.

Algoritm pentru obținerea codului complementar al unui număr negativ.

Pentru a obține un cod suplimentar de k-biți al unui număr negativ, trebuie să:

    modulul unui număr negativ este reprezentat prin cod direct în k cifre binare;

    inversează valoarea tuturor biților: înlocuiți toate zerourile cu unu și cele cu zerouri, astfel, se obține un cod invers de k-biți al numărului original);

    la cel primit cod invers adauga unu.

Exemplu:

Obținem codul complementar pe 8 biți pentru numărul -52:
00110100 - numărul |-52|=52 în cod direct
11001011 - numărul -52 în cod invers
11001100 - numărul -52 în codul complementar

Performanţă numere realeîn calculator.

Pentru a reprezenta numere reale în calculatoare moderne metoda acceptata reprezentări în virgulă mobilă.

Această metodă de reprezentare se bazează pe notația normalizată (exponențială) a numerelor reale.
Notație normalizată diferită de zero numar real A este o înregistrare ca:
A= m* q n ,
Unde
m - mantisa numărului ( Fracțiunea corespunzătoare, în care prima cifră după virgulă zecimală nu este zero),
q este baza sistemului,
n - ordinea numerelor.

Exemple:
1. 3,1415926 = 0, 31415926 * 101;
2. 1000=0,1 * 104;
3. 0,123456789 = 0,123456789 * 100;
4. 0,00001078 = 0,1078 * 8-4; (ordinea este scrisă în al 10-lea sistem)
5. 1000,00012 = 0, 100000012 * 24.

Când reprezintă numere în virgulă mobilă, o parte din cifrele celulei este alocată pentru a înregistra ordinea numărului, cifrele rămase sunt alocate pentru a înregistra mantisa. O cifră în fiecare grup este alocată pentru a reprezenta semnul de ordine și semnul mantisei.

În vremurile străvechi, pentru industria IT era anii 70 ai secolului trecut, matematicienii (cum erau numiți anterior programatorii) luptau ca Don Quijote într-o luptă inegală cu computerele, care atunci aveau dimensiunea unor mici mori de vânt. Sarcinile erau serioase: căutarea submarinelor inamice în ocean folosind imagini de pe orbită, calcularea balisticii rachetelor raza lunga, Și așa mai departe. Pentru a le rezolva, computerul trebuie să opereze cu numere reale, care, după cum știm, sunt un continuum, în timp ce memoria este finită. Prin urmare, trebuie să mapam acest continuum pe un set finit de zerouri și unu. În căutarea unui compromis între viteza, dimensiunea și acuratețea reprezentării, oamenii de știință au propus numere în virgulă mobilă (sau în virgulă mobilă, dacă sunt în burghezie).

Din anumite motive, aritmetica în virgulă mobilă este considerată un câmp exotic informatică, având în vedere că tipurile de date corespunzătoare sunt prezente în fiecare limbaj de programare. Sincer să fiu, nu am acordat niciodată prea multă importanță aritmeticii computerului, în timp ce rezolvând aceeași problemă pe CPU și GPU, am obținut rezultate diferite. S-a dovedit că fenomene foarte curioase și ciudate sunt ascunse în colțurile secrete ale acestei zone: non-comutativitatea și neasociativitatea operațiilor aritmetice, zero cu semn, diferența de numere inegale dă zero și așa mai departe. Rădăcinile acestui aisberg pătrund adânc în matematică, iar sub tăietură voi încerca să contur doar ceea ce se află la suprafață.

1. Bazele

Mulțimea numerelor întregi este infinită, dar putem alege întotdeauna un număr de biți pentru a reprezenta orice număr întreg care apare la rezolvarea sarcina specifica. Mulțimea numerelor reale nu este doar infinită, ci și continuă, așa că indiferent de câți biți luăm, inevitabil vom întâlni numere care nu au o reprezentare exactă. Numerele în virgulă mobilă sunt unul dintre moduri posibile reprezentarea numerelor reale, care reprezintă un compromis între acuratețe și intervalul de valori acceptate.

Un număr în virgulă mobilă constă dintr-un set de cifre individuale, împărțite în mod convențional în semn, exponent și mantisă. Exponentul și mantisa sunt numere întregi care, împreună cu semnul, dau reprezentarea unui număr în virgulă mobilă în urmatoarea forma:

Matematic se scrie asa:

(-1) s × M × B E, unde s este semnul, B este radixa, E este exponentul și M este mantisa.

Baza determină sistemul numeric al cifrelor. S-a dovedit matematic că numerele în virgulă mobilă cu baza B=2 (reprezentare binară) sunt cele mai rezistente la erorile de rotunjire, prin urmare în practică se întâlnesc doar bazele 2 și, mai rar, 10. Pentru o prezentare ulterioară, vom presupune întotdeauna B= 2, iar formula pentru un număr cu virgulă mobilă va arăta astfel:

(-1) s × M × 2 E

Ce este mantisa și ordinea? mantisa este un număr întreg cu lungime fixă ​​care reprezintă cei mai semnificativi biți ai unui număr real. Să presupunem că mantisa noastră este formată din trei biți (|M|=3). Luați, de exemplu, numărul „5”, care în sistemul binar va fi egal cu 101 2. Cel mai semnificativ bit corespunde lui 2 2 =4, bitul mijlociu (pe care îl avem egal cu zero) 2 1 =2, iar cel mai mic 2 0 =1. Ordin– aceasta este puterea bazei (două) a celei mai mari cifre. În cazul nostru E=2. Este convenabil să scrieți astfel de numere în așa-numitul „științific” forma standard, de exemplu „1.01e+2”. Este imediat clar că mantisa constă din trei semne, iar ordinea este două.

Să zicem că vrem să obținem un număr fracționar, folosind aceiași 3 biți ai mantisei. Putem face acest lucru dacă luăm, să zicem, E=1. Atunci numărul nostru va fi egal

1.01e+1 = 1×2 1 +0×2 0 +1×2 -1 =2+0.5=2.5

Aici, deoarece E=1, puterea a două din prima cifră (care vine înainte de virgulă zecimală) este „1”. Celelalte două cifre situate în dreapta (după virgulă zecimală) oferă o contribuție de 2 E-1 și 2 E-2 (2 0 și, respectiv, 2 -1). Este evident că prin ajustarea lui E același număr poate fi reprezentat în moduri diferite. Să luăm în considerare un exemplu cu lungimea mantisei |M|=4. Numărul „2” poate fi reprezentat astfel:

2 = 10 (în binar) = 1.000e+1 = 0.100e+2 = 0.010e+3. (E=1, E=2, respectiv E=3)

Vă rugăm să rețineți că același număr are mai multe reprezentări. Acest lucru nu este convenabil pentru echipament, deoarece... este necesar să se ţină cont de multiplicitatea reprezentării la compararea numerelor şi la efectuarea operaţiilor aritmetice asupra acestora. Mai mult, nu este economic, deoarece numărul de reprezentări este finit, iar repetarea reduce numărul de numere care pot fi reprezentate. Prin urmare, deja în primele mașini au început să folosească un truc, făcând primul bit al mantisei întotdeauna pozitiv. Această prezentare a fost numită normalizat.

Acest lucru economisește un bit, deoarece cel implicit nu trebuie să fie stocat în memorie și asigură că numărul este reprezentat unic. În exemplul nostru, „2” are o singură reprezentare normalizată („1.000e+1”), iar mantisa este stocată în memorie ca „000”, deoarece unitatea conducătoare este implicită. Dar în reprezentarea normalizată a numerelor apare noua problema- este imposibil de reprezentat zero în această formă.

Strict vorbind, un număr normalizat are următoarea formă:

(-1) s × 1.M × 2 E .

Calitatea rezolvării problemelor depinde în mare măsură de alegerea reprezentării în virgulă mobilă. Am abordat treptat problema standardizării unei astfel de reprezentări.

2. Puțină istorie

În anii 60 și 70, nu exista un standard unic pentru reprezentarea numerelor în virgulă mobilă, a metodelor de rotunjire sau a operațiilor aritmetice. Drept urmare, programele erau extrem de neportabile. Dar de asemenea problema mai mare avea ce diferite calculatoare erau niște „ciudățeni” și trebuiau cunoscute și luate în considerare în program. De exemplu, diferența a două numere inegale a returnat zero. Ca urmare, expresiile „X=Y” și „X-Y=0” au intrat în conflict. Meșterii au rezolvat această problemă cu trucuri foarte inteligente, de exemplu, făcând atribuirea „X=(X-X)+X” înainte de operațiile de înmulțire și împărțire pentru a evita problemele.

Inițiativa de a crea standard unic pentru reprezentarea numerelor în virgulă mobilă a coincis în mod suspect cu încercările din 1976 ale Intel de a dezvolta o aritmetică „mai bună” pentru noile coprocesoare 8086 și i432. Dezvoltarea a fost întreprinsă de oamenii de știință din acest domeniu, prof. John Palmer și William Kahan. Acesta din urmă, într-un interviu, și-a exprimat părerea că seriozitatea cu care Intel și-a dezvoltat aritmetica a forțat alte companii să se unească și să înceapă procesul de standardizare.

Toată lumea a vorbit serios, pentru că este foarte profitabil să-ți promovezi arhitectura și să o faci standard. DEC, National Superconductor, Zilog și Motorola și-au prezentat propunerile. Producătorii de mainframe Cray și IBM au urmărit de pe margine. Compania Intel, desigur, și-a prezentat și noua ei aritmetică. Autorii specificației propuse au fost William Kahan, Jeromy Kunen și Harold Stone, iar propunerea lor a fost imediat supranumită „K-C-S”.

Aproape imediat, toate propunerile, cu excepția a două, au fost eliminate: VAX de la DEC și „K-C-S” de la Intel. Specificația VAX era mult mai simplă, era deja implementată în calculatoarele PDP-11 și era clar cum să obțineți performanță maximă. Pe de altă parte, „K-C-S” conținea o mulțime de funcționalități utile, cum ar fi numere „speciale” și „denormalizate” (detalii mai jos).

În „K-C-S” toți algoritmii aritmetici sunt strict specificați și se cere ca rezultatul implementării să coincidă cu aceștia. Acest lucru permite efectuarea unor calcule stricte în cadrul acestei specificații. Dacă anterior un matematician a rezolvat o problemă folosind metode numerice și a dovedit proprietățile soluției, nu exista nicio garanție că aceste proprietăți vor fi păstrate în program. Rigoarea aritmeticii K-C-S a făcut posibilă demonstrarea teoremelor folosind aritmetica în virgulă mobilă.

DEC a făcut totul pentru a face ca specificațiile sale un standard. Ea a obținut chiar și sprijinul unor oameni de știință de renume că aritmetica K-C-S nu ar putea, în principiu, să atingă aceeași performanță ca DEC. Ironia este că Intel a știut să facă ca specificațiile sale ca fiind performante, dar aceste trucuri erau un secret comercial. Dacă Intel nu ar fi cedat și nu și-ar fi dezvăluit unele dintre secretele sale, nu ar fi fost capabilă să rețină asaltul DEC.

Pentru mai multe despre bătăliile de standardizare, vedeți interviul profesorului Kahan și ne vom uita la cum arată acum reprezentarea în virgulă mobilă.

3. Reprezentarea numerelor în virgulă mobilă astăzi

Dezvoltatorii K-C-S au câștigat și acum ideea lor a devenit standardul IEEE754. Reprezintă numere în virgulă mobilă ca semn (s), mantisă (M) și exponent (E) după cum urmează:

(-1)s × 1.M × 2 E

Cometariu.În noul standard IEE754-2008, pe lângă numerele cu baza 2, există numere cu baza 10, așa-numitele zecimal numere (zecimale) în virgulă mobilă.

Pentru a nu copleși cititorul cu informații excesive care pot fi găsite pe Wikipedia, vom lua în considerare un singur tip de date, o singură precizie (float). Numerele de precizie jumătate, duble și extinse au aceleași caracteristici, dar au o gamă diferită de ordine și mantisă. În numerele de precizie unică (float/single), ordinea constă din 8 biți, iar mantisa - din 23. Ordinea efectivă este definită ca E-127. De exemplu, numărul 0,15625 ar fi stocat în memorie ca

Cifra luată de pe Wikipedia

În acest exemplu:

  • Semnul s=0 (număr pozitiv)
  • Comanda E=01111100 2 -127 10 = -3
  • Mantissa M = 1,01 2 (prima unitate nu este explicită)
  • Ca rezultat, numărul nostru F = 1,01 2 e-3 = 2 -3 +2 -5 = 0,125 + 0,03125 = 0,15625

O explicație puțin mai detaliată

Aici avem de-a face cu o reprezentare binară a numărului „101” cu punctul zecimal deplasat de câteva locuri spre stânga. 1.01 este o reprezentare binară care înseamnă 1×2 0 + 0×2 -1 + 1×2 -2 . Mutând virgulă zecimală cu trei poziții la stânga obținem 1.01e-3 = 1×2 -3 + 0×2 -4 + 1×2 -5 = 1×0.125 + 0×0.0625 + 1×0.03125 = 0.125 + 0 . 03125 = 0,15625.

3.1 Numere speciale: zero, infinit și incertitudine
În IEEE754, numărul „0” este reprezentat de o valoare cu un ordin egal cu E=E min -1 (pentru single aceasta este -127) și o mantisă zero. Introducerea lui zero ca număr independent (deoarece zero nu poate fi reprezentat într-o reprezentare normalizată) a făcut posibilă evitarea multor ciudățenii în aritmetică. Și deși operațiunile cu zero trebuie procesate separat, ele sunt de obicei efectuate mai rapid decât cu numerele obișnuite.

IEEE754 oferă, de asemenea, o reprezentare pentru numere speciale, a căror funcționare provoacă o excepție. Aceste numere includ infinitul (±∞) și incertitudinea (NaN). Aceste numere vă permit să returnați o valoare adecvată în caz de depășire. Infiniturile sunt reprezentate ca numere cu ordinul E=E max +1 și mantisa zero. Puteți obține infinitul cu debordare și divizare număr diferit de zero la zero. Dezvoltatorii au determinat infinitul în diviziune pe baza existenței unor limite atunci când dividendul și divizorul tind la un anumit număr. În consecință, c/0==±∞ (de exemplu, 3/0=+∞ și -3/0=-∞), deoarece dacă dividendul tinde spre o constantă și divizorul tinde spre zero, limita este egală cu infinit. La 0/0 nu există limită, deci rezultatul va fi incertitudine.

Incertitudine sau NaN (de la nu un număr) este o reprezentare inventată cu scopul de a operație aritmetică ar putea returna întotdeauna o valoare fără sens. În IEEE754, NaN este reprezentat ca un număr în care E=E max +1 și mantisa este diferită de zero. Orice operație cu NaN returnează NaN. Dacă doriți, puteți scrie informații în mantise pe care programul le poate interpreta. Acest lucru nu este specificat de standard și mantisa este cel mai adesea ignorată.

Cum poți obține NaN? Într-unul din următoarele moduri:

  • ∞+(- ∞)
  • 0 × ∞
  • 0/0, ∞/∞
  • sqrt(x), unde x<0
Prin definiție, NaN ≠ NaN, prin urmare, pentru a verifica valoarea unei variabile, trebuie doar să o comparați cu ea însăși.
De ce zero are un semn (sau +0 vs -0)
Cititorul iscoditor a observat probabil deja că în reprezentarea descrisă a numerelor în virgulă mobilă există două zerouri care diferă doar prin semn. Deci, 3·(+0)=+0 și 3·(-0)=-0. Dar când comparăm +0=-0. În standard, semnul a fost reținut în mod deliberat, astfel încât expresiile care, ca urmare a depășirii sau a depășirii, se transformă în infinit sau zero, să poată prezenta cel mai corect rezultat atunci când sunt înmulțite și împărțite. De exemplu, dacă zero nu ar avea semn, expresia 1/(1/x)=x nu ar fi adevărată la x=±∞, deoarece 1/∞ și 1/-∞ sunt egale cu 0.

Inca un exemplu:
(+∞/0) + ∞ = +∞, în timp ce (+∞/-0) +∞ = NaN

De ce este infinitul mai bun decât NaN în acest caz? Pentru că dacă NaN apare într-o expresie aritmetică, rezultatul întregii expresii va fi întotdeauna NaN. Dacă infinitul este întâlnit în expresie, atunci rezultatul poate fi zero, infinit sau un număr obișnuit cu virgulă mobilă. De exemplu, 1/∞=0.

3.3 Numerele denormalizate
Să ne uităm la ce numere denormalizate subnormale sunt folosind un exemplu simplu. Să avem o reprezentare normalizată cu o lungime a mantisei |M|=2 biți (+ un bit de normalizare) și un interval de valori de ordinul -1≤E≤2. În acest caz, obținem 16 numere:

Trazele mari arată numere cu o mantisă egală cu 1,00. Se poate observa că distanța de la zero la cel mai apropiat număr (0 - 0,5) este mai mare decât de la acest număr la următorul (0,5 - 0,625). Aceasta înseamnă că diferența dintre oricare două numere de la 0,5 la 1 va da 0, chiar dacă aceste numere nu sunt egale. Ceea ce este și mai rău este că diferența dintre numerele mai mari decât 1 se încadrează în decalajul dintre 0,5 și 0. De exemplu, „1,5-1,25=0” (vezi imaginea).

Nu orice program intră în „gaura aproape de zero”. Conform statisticilor din anii 70, în medie, fiecare computer întâmpina această problemă o dată pe lună. Având în vedere că computerele deveneau răspândite, dezvoltatorii K-C-S au considerat această problemă suficient de serioasă pentru a fi rezolvată la nivel hardware. Soluția propusă de ei a fost următoarea. Știm că cu E=E min -1 (pentru float acesta este „-127”) și o mantisă zero, numărul este considerat egal cu zero. Dacă mantisa nu este zero, atunci numărul este considerat nu zero, ordinea sa este setată la E=E min , iar bitul înalt implicit al mantisei este setat la zero. Se numesc astfel de numere denormalizat.

Strict vorbind, numerele în virgulă mobilă arată acum astfel:

(-1) s × 1.M × 2 E dacă E min ≤E≤E max (numere normalizate)

(-1) s × 0.M × 2 Emin dacă E=E min -1. (numere denormalizate)

Să revenim la exemplu. E minul nostru =-1. Să introducem o nouă valoare de ordine, E=-2, la care numerele sunt denormalizate. Ca rezultat, obținem o nouă reprezentare a numerelor:

Intervalul de la 0 la 0,5 este umplut cu numere denormalizate, ceea ce face posibil să nu eșueze în cele 0 exemple discutate mai sus (0,5-0,25 și 1,5-1,25). Acest lucru a făcut reprezentarea mai robustă la erorile de rotunjire pentru numere apropiate de zero.

Dar luxul de a folosi o reprezentare denormalizată a numerelor în procesor nu vine gratuit. Deoarece astfel de numere trebuie să fie tratate diferit în toate operațiunile aritmetice, este dificil să faci o astfel de aritmetică să funcționeze eficient. Acest lucru impune dificultăți suplimentare la implementarea ALU-urilor în procesor. Și, în timp ce numerele denormalizate sunt foarte utile, ele nu sunt un panaceu și rotunjirea la zero încă trebuie să fie îngrijită. Prin urmare, această funcționalitate a devenit o piatră de poticnire în timpul dezvoltării standardului și a întâlnit cea mai puternică rezistență.

3.4 Ordinea numerelor în IEEE754
Una dintre caracteristicile uimitoare ale reprezentării numerelor IEEE754 este că exponentul și mantisa sunt aranjate unul după altul în așa fel încât împreună formează o secvență de numere întregi (n) pentru care este valabil următoarele:

N

Deci, dacă luăm un număr cu virgulă mobilă pozitiv, îl convertim într-un număr întreg, adăugăm „1”, obținem următorul număr care este reprezentabil în această aritmetică. În C poți face așa:

Float a=0,5; int n = *((int*) &a); float b = *((float*) &(++n)); printf("După %e următorul număr: %e, diferență (%e)\n", a, b, b-a);
Acest cod va funcționa numai pe o arhitectură int pe 32 de biți.

4. Capcane în aritmetica în virgulă mobilă

Acum - să exersăm. Să ne uităm la caracteristicile aritmeticii în virgulă mobilă care necesită o atenție specială la programare.
4.1 Rotunjire
Erorile datorate erorilor de rotunjire sunt greu de întâlnit în aritmetica modernă în virgulă mobilă, mai ales când se utilizează precizia dublă. Regula de rotunjire din standardul IEEE754 prevede că rezultatul oricărei operații aritmetice trebuie să fie ca și cum ar fi fost efectuat pe valorile exacte și rotunjit la cel mai apropiat număr reprezentabil în formatul respectiv. Acest lucru necesită efort suplimentar din partea ALU, iar unele opțiuni ale compilatorului (cum ar fi „-ffast-math” în gcc) pot dezactiva acest comportament. Caracteristici de rotunjire IEEE754:
  • Rotunjirea la cea mai apropiată din standard se face altfel decât suntem obișnuiți. S-a arătat matematic că dacă 0,5 este rotunjit la 1 (în sus), atunci există un set de operații în care eroarea de rotunjire va crește la infinit. Prin urmare, IEEE754 folosește regula rotunjită la egală. Deci, 12,5 va fi rotunjit la 12, iar 13,5 va fi rotunjit la 14.
  • Cea mai periculoasă operație în ceea ce privește rotunjirea în aritmetica în virgulă mobilă este scăderea. La scăderea numerelor apropiate, se pot pierde cifre semnificative, ceea ce
    poate crește eroarea relativă de mai multe ori.
  • Pentru multe formule matematice utilizate pe scară largă, matematicienii au dezvoltat o formă specială care poate reduce semnificativ erorile de rotunjire. De exemplu, este mai bine să calculați formula „x 2 -y 2” folosind formula „(x-y)(x+y)”.
4.2 Neasociativitatea operațiilor aritmetice
În aritmetica cu virgulă mobilă, regula (a*b)*c = a*(b*c) nu este valabilă pentru nicio operație aritmetică. De exemplu,

(10 20 +1)-10 20 =0 ≠ (10 20 -10 20)+1=1

Să presupunem că avem un program pentru însumarea numerelor.

s dublu = 0,0; pentru (int i=0; i Unii compilatori pot rescrie implicit codul pentru a utiliza mai multe ALU în același timp (presupunând că n este divizibil cu 2):

Double sa, s; sa=sa=0,0; pentru (int i=0; i Deoarece operațiile de sumă nu sunt asociative, cele două programe pot produce rezultate diferite.

4.3 Constante numerice
Amintiți-vă că nu toate numerele zecimale au o reprezentare binară în virgulă mobilă. De exemplu, numărul „0,2” ar fi reprezentat ca „0,200000003” cu precizie unică. În consecință, „0,2 + 0,2 ≈ 0,4”. Eroare absolută la individ
În acest caz, poate să nu fie mare, dar dacă folosim o astfel de constantă într-o buclă, putem obține eroarea acumulată.
4.4 Selectarea minimului a două valori
Să presupunem că trebuie să alegem minimul dintre două valori. În C, acest lucru se poate face în unul dintre următoarele moduri:
  1. X< y? x: y
  2. X<= y? x: y
  3. x > y? y: x
  4. x >= y? y: x
Adesea compilatorul le consideră echivalente și folosește întotdeauna prima opțiune, deoarece este executată într-o instrucțiune de procesor. Dar dacă luăm în considerare ±0 și NaN, aceste operații nu sunt în niciun fel echivalente:
X y X< y? x: y X<= y? x: y x > y? y: x x >= y? y: x
+0 -0 -0 +0 +0 -0
NaN 1 1 1 NaN NaN
4.5 Compararea numerelor
O greșeală foarte frecventă când se lucrează cu flotoare apare atunci când se verifică egalitatea. De exemplu,

Float fValue = 0,2; if (fValue == 0,2) DoStuff();
Eroarea aici este, în primul rând, că 0,2 nu are o reprezentare binară exactă, iar în al doilea rând, 0,2 este o constantă de dublă precizie, iar variabila fValue este simplă și nu există nicio garanție cu privire la comportamentul acestei comparații.

Cea mai bună, dar totuși eronată, este de a compara diferența cu eroarea absolută permisă:

Dacă (fabs(fValue – fExpected)< 0.0001) DoStuff(); // fValue=fExpected?

Dezavantajul acestei abordări este că eroarea în reprezentarea unui număr crește pe măsură ce numărul în sine crește. Deci, dacă programul așteaptă „10000”, atunci egalitatea de mai sus nu va fi valabilă pentru cel mai apropiat număr vecin (10000,000977). Acest lucru este valabil mai ales dacă programul conține o conversie de la precizie simplă la precizie dublă.

Alegerea corectă a procedurii de comparare este dificilă și trimit cititorii interesați la articolul lui Bruce Dawson. Acesta propune compararea numerelor în virgulă mobilă prin conversia lor într-o variabilă întreagă. Acesta este cel mai bun mod, deși nu portabil:

Bool AlmostEqual2sComplement(float A, float B, int maxUlps) ( // maxUlps nu trebuie să fie negativ și nu prea mare, astfel încât // NaN să nu fie egal cu niciun număr assert(maxUlps > 0 && maxUlps< 4 * 1024 * 1024); int aInt = *(int*)&A; // Уберем знак в aInt, если есть, чтобы получить правильно упорядоченную последовательность if (aInt < 0) aInt = 0x80000000 - aInt; //aInt &= 0x7fffffff; //(см. комментарий пользователя Vayun) // Аналогично для bInt int bInt = *(int*)&B; if (bInt < 0) bInt = 0x80000000 - bInt; /*aInt &= 0x7fffffff;*/ unsigned int intDiff = abs(aInt - bInt); /*(см. комментарий пользователя Vayun)*/ if (intDiff <= maxUlps) return true; return false; }

În acest program, maxUlps (de la Units-In-Last-Place) este numărul maxim de numere în virgulă mobilă care se pot situa între valoarea testată și valoarea așteptată. O altă semnificație a acestei variabile este numărul de cifre binare (începând cu cele mai puțin semnificative) din numerele comparate care pot fi omise. De exemplu, maxUlps=16 înseamnă că cei 4 biți inferiori (log 2 16) s-ar putea să nu se potrivească, dar numerele vor fi în continuare considerate egale. În acest caz, în comparație cu numărul 10000, eroarea absolută va fi egală cu 0,0146, iar în comparație cu 0,001, eroarea va fi mai mică de 0,00000001 (10 -8).

5. Verificarea caracterului complet al suportului IEE754

Credeți că dacă procesoarele respectă pe deplin standardul IEEE754, atunci orice program care utilizează tipuri de date standard (cum ar fi float/double în C) va produce același rezultat pe computere diferite? Nu aveți dreptate. Portabilitatea și conformitatea cu standardul sunt afectate de opțiunile de compilare și de optimizare. William Kahan a scris un program în C (există și o versiune pentru Fortran) care vă permite să verificați dacă combinația „arhitectură + compilator + opțiuni” satisface IEEE754. Se numește „Paranoia în virgulă mobilă” și textele sale sursă sunt disponibile pentru descărcare. Un program similar este disponibil pentru GPU-uri. De exemplu, Intel Compiler (icc) utilizează implicit modelul IEEE754 „relaxat” și, ca urmare, nu rulează toate testele. Opțiunea „-fp-model precise” vă permite să compilați programul exact la standard. Compilatorul GCC are o opțiune „-ffast-math” care cauzează neconformitatea IEEE754.

Concluzie

În sfârșit, o poveste instructivă. Când lucram la un proiect de testare pe GPU, aveam o versiune în serie și paralelă a aceluiași program. După ce am comparat timpul de execuție, am fost foarte fericit pentru că am primit o accelerare de 300x. Dar mai târziu s-a dovedit că calculele pe GPU „s-au destramat” și s-au transformat în NaN, iar lucrul cu ele în GPU a fost mai rapid decât cu numerele obișnuite. Un alt lucru a fost interesant - același program de pe emulator GPU (pe CPU) a produs rezultatul corect, dar pe GPU în sine nu. Ulterior s-a dovedit că problema a fost că acest GPU nu suporta pe deplin standardul IEEE754 și abordarea directă nu a funcționat.

Aritmetica în virgulă mobilă este acum aproape perfectă. Aproape întotdeauna, o abordare naivă va funcționa, iar un program care nu ia în considerare toate caracteristicile sale va produce rezultatul corect, iar capcanele descrise se referă doar la cazuri exotice. Dar trebuie să rămâneți mereu vigilenți: într-o chestiune precum matematica computerizată este ușor să călcați pe greblă.
! Adaugă etichete

Instrucțiuni

Dacă în formă fractii trebuie să ne imaginăm întregul număr, apoi utilizați unul ca numitor și puneți valoarea inițială în numărător. Această formă de notație se numește fracție ordinară improprie, deoarece modulul numărătorului său este mai mare decât modulul numitorului. De exemplu, număr 74 poate fi scris ca 74/1 și număr-12 - ca -12/1. Dacă este necesar, puteți număra și numitor de același număr de ori - valoare fractiiîn acest caz, se va potrivi în continuare cu numărul inițial. De exemplu, 74=74/1=222/3 sau -12=-12/1=-84/7.

Dacă originalul număr prezentate în format zecimal fractii, apoi lăsați întreaga parte neschimbată și înlocuiți virgula de separare cu un spațiu. Puneți partea fracțională în numărător și, ca numitor, folosiți un zece ridicat la o putere cu un exponent egal cu numărul de cifre din fracția numărului original. Partea fracțională rezultată poate fi redusă prin împărțirea numărătorului și numitorului la același număr. De exemplu, zecimală fractii 7,625 va corespunde fracției comune 7 625/1000, care după reducere va lua valoarea 7 5/8. Această formă de notație este comună fractii amestecat. Dacă este necesar, poate fi redusă la forma obișnuită greșită prin înmulțirea părții întregi cu numitorul și adăugarea rezultatului la numărător: 7,625 = 7.625/1000 = 7 5/8 = 61/8.

Dacă fracția zecimală inițială este și periodică, atunci utilizați, de exemplu, un sistem de ecuații pentru a calcula echivalentul său în format fractii comun. Să presupunem că, dacă fracția inițială este 3,5(3), atunci putem avea o identitate: 100*x-10*x=100*3,5(3)-10*3,5(3). Din ea putem deduce egalitatea 90*x=318, și că fracția dorită va fi egală cu 318/90, care după reducere va da o fracție obișnuită 3 24/45.

Surse:

  • Numărul 450.000 poate fi reprezentat ca produsul a 2 numere?

În viața de zi cu zi, numerele nenaturale sunt cel mai des întâlnite: 1, 2, 3, 4 etc. (5 kg de cartofi) și numere fracționate, neîntregi (5,4 kg de ceapă). Cele mai multe dintre ele sunt prezentate în formă fracții zecimale. Dar reprezentați fracția zecimală în formă fractii destul de simplu.

Instrucțiuni

De exemplu, este dat numărul „0,12”. Dacă nu această fracție și imaginați-o așa cum este, atunci va arăta astfel: 12/100 („doisprezece”). Pentru a scăpa de o sută în , trebuie să împărțiți atât numărătorul, cât și numitorul la numărul care le împarte numerele. Acest număr este 4. Apoi, împărțind numărătorul și numitorul, obținem numărul: 3/25.

Dacă luăm în considerare un produs mai obișnuit, atunci este adesea clar pe eticheta de preț că greutatea acestuia este, de exemplu, 0,478 kg sau așa mai departe. Acest număr este, de asemenea, ușor de imaginat în formă fractii:
478/1000 = 239/500. Această fracție este destul de urâtă și, dacă ar fi posibil, această fracție zecimală ar putea fi redusă și mai mult. Și toate folosind aceeași metodă: selectarea unui număr care împarte atât numărătorul, cât și numitorul. Acest număr are cel mai mare factor comun. Factorul este „cel mai mare”, deoarece este mult mai convenabil să împărțiți imediat atât numărătorul, cât și numitorul cu 4 (ca în primul exemplu) decât să îl împărțiți de două ori la 2.

Video pe tema

Zecimal fracțiune- varietate fractii, care are un număr „rotund” la numitor: 10, 100, 1000 etc., De exemplu, fracțiune 5/10 are o notație zecimală de 0,5. Pe baza acestui principiu, fracțiune poate fi reprezentat în formă zecimal fractii.

Instrucțiuni

Trăim într-o lume digitală. Dacă anterior principalele valori erau pământul, banii sau mijloacele de producție, acum tehnologia și informația decid totul. Fiecare persoană care vrea să reușească este pur și simplu obligată să înțeleagă orice numere, indiferent sub ce formă sunt prezentate. Pe lângă forma obișnuită de notație zecimală, există multe alte modalități convenabile de a reprezenta numere (în contextul unor sarcini specifice). Să ne uităm la cele mai comune dintre ele.

Vei avea nevoie

  • Calculator

Instrucțiuni

Pentru a reprezenta un număr zecimal ca o fracție, mai întâi trebuie să vă uitați dacă este un număr real sau un număr real. Întreg număr nu are virgulă deloc, sau există un zero după virgulă (sau multe zerouri, care este același lucru). Dacă există câteva numere după virgulă, atunci aceasta număr se referă la cele reale. Întreg număr foarte ușor de reprezentat ca fracție: numărătorul însuși intră în număr, iar numitorul este . Cu zecimala este aproape la fel, doar că vom înmulți ambele părți ale fracției cu zece până scăpăm de virgula din numărător.

| Planificarea lecțiilor pentru anul universitar (FSES) | § 1.2. Reprezentarea numerelor într-un computer

Lecțiile 6 - 7
§ 1.2. Reprezentarea numerelor într-un computer

Cuvinte cheie:

Descarcare
reprezentare întreg fără semn
reprezentare întreg cu semn
reprezentarea numerelor reale

1.2.1. Reprezentare intreg

RAM-ul unui computer este format din celule, fiecare dintre acestea fiind un sistem fizic format dintr-un anumit număr de elemente omogene. Aceste elemente au două stări stabile, dintre care una corespunde zero, iar cealaltă uneia. Fiecare astfel de element este folosit pentru a stoca unul dintre biți - o cifră a unui număr binar. De aceea fiecare element de celulă este numit bit sau cifră (Fig. 1.2).

Orez. 1.2. Celula de memorie

Pentru reprezentarea computerizată a numerelor întregi, se folosesc mai multe metode diferite, care diferă unele de altele prin numărul de cifre (numărul întregi sunt de obicei alocate 8, 16, 32 sau 64 de cifre) și prezența sau absența unei cifre semn. Reprezentarea fără semn poate fi utilizată numai pentru numere întregi nenegative; numerele negative pot fi reprezentate numai sub formă de semn.

Reprezentarea nesemnată este utilizată pentru obiecte precum adresele celulelor, diferite contoare (de exemplu, numărul de caractere din text), precum și numerele care indică data și ora, dimensiunile pixelilor imaginilor grafice etc.

Valoarea maximă a unui număr întreg nenegativ este atinsă atunci când toți biții celulei îi conțin. Pentru reprezentarea pe n biți va fi egal cu 2 n -1. Numărul minim corespunde la n zerouri stocate în n biți de memorie și este egal cu zero.

Următoarele sunt valorile maxime pentru numerele întregi fără semn pe n biți:

Pentru a obține o reprezentare computerizată a unui întreg fără semn, este suficient să convertiți numărul în sistemul de numere binar și să completați rezultatul rezultat din stânga cu zerouri la capacitatea de cifre standard.

Exemplul 1. Numărul 53 10 = 110101 2 în reprezentare din opt cifre are forma:

Același număr 53 din șaisprezece cifre va fi scris după cum urmează:

Când este reprezentată cu un semn, cea mai semnificativă cifră (stânga) este atribuită semnului numărului, cifrele rămase sunt atribuite numărului însuși. Dacă numărul este pozitiv, atunci 0 este plasat în bitul de semn, dacă numărul este negativ - 1. Această reprezentare a numerelor se numește cod direct.

În computere, codurile directe sunt folosite pentru a stoca numere pozitive în dispozitivele de stocare pentru a efectua operațiuni pe numere pozitive.

Site-ul web al Centrului Federal pentru Informații și Resurse Educaționale (http://fcior.edu.ru/) conține modulul de informații „Numărul și codul său de calculator”. Cu această resursă puteți obține informații suplimentare despre tema pe care o studiați.

Pentru a efectua operații pe numere negative, se folosește un cod suplimentar pentru a înlocui operația de scădere cu adunarea. Puteți afla algoritmul pentru generarea unui cod suplimentar folosind modulul de informații „Cod suplimentar” aflat pe site-ul web al Centrului Federal pentru Informații și Resurse Educaționale (http://fcior.edu.ru/).

1.2.2. Reprezentarea numerelor reale

Orice număr real A poate fi scris în formă exponențială:

Unde:

m - mantisa numărului;

p - ordinea numerelor.

De exemplu, numărul 472 LLC LLC poate fi reprezentat astfel: 4,72 10 8, 47,2 10 7, 472,0 10 6 etc.

Este posibil să fi întâlnit forma exponențială de scriere a numerelor atunci când efectuați calcule folosind un calculator, când ați primit intrări de următoarea formă ca răspuns: 4.72E+8.

Aici, semnul „E” denotă baza sistemului numeric zecimal și este citit ca „înmulțire cu zece la putere”.

Din exemplul de mai sus, puteți vedea că poziția punctului zecimal într-un număr se poate modifica.

Pentru consecvență, mantisa este de obicei scrisă ca o fracție proprie cu o cifră diferită de zero după virgulă. În acest caz, numărul 472 LLC LLC va fi reprezentat ca 0,472 10 9.

Un număr real poate ocupa 32 sau 64 de biți în memoria computerului. În acest caz, biții sunt alocați pentru a stoca semnul mantisei, semnul comenzii, ordinea și mantisa.

Exemplu:

Gama de reprezentare a numerelor reale este determinată de numărul de biți alocați pentru a stoca ordinea numărului, iar precizia este determinată de numărul de biți alocați pentru a stoca mantisa.

Valoarea maximă a ordinii numerelor pentru exemplul de mai sus este 1111111 2 = 127 10 și, prin urmare, valoarea maximă a numărului este:

0,11111111111111111111111 10 1111111

Încercați să vă dați seama singur care este echivalentul zecimal al acestei valori.

O gamă largă de reprezentări ale numerelor reale este importantă pentru rezolvarea problemelor științifice și de inginerie. În același timp, trebuie înțeles că algoritmii de procesare a unor astfel de numere necesită mai multă muncă în comparație cu algoritmii de procesare a numerelor întregi.

CEL MAI IMPORTANT

Pentru a reprezenta numerele întregi pe un computer, se folosesc mai multe metode diferite, care diferă unele de altele prin numărul de cifre (8, 16, 32 sau 64) și prezența sau absența unei cifre semn.

Pentru a reprezenta un întreg fără semn, acesta ar trebui convertit în sistemul de numere binar, iar rezultatul rezultat ar trebui să fie completat în stânga cu zerouri la capacitatea standard.

Când este reprezentată cu un semn, cea mai semnificativă cifră este atribuită semnului numărului, cifrele rămase sunt atribuite numărului însuși. Dacă numărul este pozitiv, atunci 0 este plasat în bitul semn, dacă numărul este negativ, atunci 1. Numerele pozitive sunt stocate în computer în cod direct, numerele negative în cod complementar.

Când se stochează numere reale într-un computer, biții sunt alocați pentru a stoca semnul ordinii numărului, ordinea în sine, semnul mantisei și mantisei. În acest caz, orice număr este scris astfel:

Unde:

m - mantisa numărului;
q - baza sistemului numeric;
p - ordinea numerelor.

Întrebări și sarcini

1. Citiți materialele de prezentare pentru paragraful conținute în anexa electronică la manual. Utilizați aceste materiale atunci când pregătiți răspunsurile la întrebări și finalizați temele.

2. Cum sunt reprezentate numerele întregi pozitive și negative în memoria computerului?

3. Orice număr întreg poate fi considerat un număr real, dar cu o parte fracțională zero. Justificați fezabilitatea de a avea modalități speciale de reprezentare computerizată a numerelor întregi.

4. Reprezentați numărul 63 10 în format nesemnat pe 8 biți.

5. Găsiți echivalentele zecimale ale numerelor folosind codurile lor directe, scrise în format semnat pe 8 biți:

a) 01001100;
b) 00010101.

6. Care dintre numerele 443 8, 101010 2, 256 10 poate fi stocat în format de 8 biți?

7. Scrie următoarele numere în formă naturală:

a) 0,3800456 10 2;
b) 0,245 10 -3;
c) 1,256900E+5;
d) 9,569120E-3.

8. Scrieți numărul 2010.0102 10 în cinci moduri diferite în formă exponențială.

9. Scrieți următoarele numere în formă exponențială cu o mantisă normalizată - o fracție proprie care are o cifră diferită de zero după virgulă:

a) 217,934 10;
b) 75321 10;
c) 0,00101 10.

10. Desenați o diagramă care conectează conceptele de bază discutate în acest paragraf.

Datele numerice sunt procesate într-un computer folosind sistemul de numere binar. Numerele sunt stocate în memoria computerului în cod binar, adică ca o secvență de zerouri și unu, și pot fi reprezentate în format fix sau flotant.

Numerele întregi sunt stocate în memorie în format fix. Cu acest format pentru reprezentarea numerelor, un registru de memorie format din opt celule de memorie (8 biți) este alocat pentru stocarea numerelor întregi nenegative. Fiecare cifră a unei celule de memorie corespunde întotdeauna aceleiași cifre a numărului, iar virgula este situată în dreapta după cifra cea mai puțin semnificativă și în afara grilei de biți. De exemplu, numărul 110011012 ar fi stocat într-un registru de memorie după cum urmează:

Tabelul 4

Valoarea maximă a unui număr întreg nenegativ care poate fi stocat într-un registru în format de virgulă fixă ​​poate fi determinată din formula: 2n – 1, unde n este numărul de cifre ale numărului. Numărul maxim va fi egal cu 28 - 1 = 25510 = 111111112 și minimul 010 = 000000002. Astfel, intervalul de modificări ale numerelor întregi nenegative va fi de la 0 la 25510.

Spre deosebire de sistemul zecimal, sistemul de numere binar în reprezentarea computerizată a unui număr binar nu are simboluri care să indice semnul numărului: pozitiv (+) sau negativ (-), prin urmare, pentru a reprezenta numere întregi cu semn în sistemul binar, două se folosesc formate de reprezentare a numerelor: formatul valorii numerelor semnate și formatul complementului a doi. În primul caz, două registre de memorie (16 biți) sunt alocate pentru stocarea numerelor întregi cu semn, iar cifra cea mai semnificativă (cel mai din stânga) este folosită ca semn al numărului: dacă numărul este pozitiv, atunci 0 este scris în bitul de semn. , dacă numărul este negativ, atunci 1. De exemplu, numărul 53610 = 00000010000110002 va fi reprezentat în registrele de memorie sub următoarea formă:

Tabelul 5

și un număr negativ -53610 = 10000010000110002 sub forma:

Tabelul 6

Numărul maxim pozitiv sau numărul minim negativ în formatul valorii numărului cu semn (ținând cont de reprezentarea unei cifre pe semn) este 2n-1 – 1 = 216-1 – 1 = 215 – 1 = 3276710 = 11111111111111112 și intervalul de numere va fi de la - 3276710 la 32767.

Cel mai adesea, pentru a reprezenta numerele întregi cu semne în sistemul binar, se utilizează formatul de cod complementar al celor două, care vă permite să înlocuiți operația aritmetică de scădere într-un computer cu o operație de adunare, care simplifică semnificativ structura microprocesorului și crește performanța acestuia. .

Pentru a reprezenta numerele întregi negative în acest format, se folosește codul complement a doi, care este modulul unui număr negativ la zero. Conversia unui întreg negativ în complement a doi se realizează folosind următoarele operații:


1) scrieți modulul numărului în cod direct în n (n = 16) cifre binare;

2) obțineți codul invers al numărului (inversați toate cifrele numărului, adică înlocuiți toate cifrele cu zerouri și zerourile cu unu);

3) adăugați una la cifra cea mai puțin semnificativă la codul invers rezultat.

De exemplu, pentru numărul -53610 în acest format, modulul va fi 00000010000110002, codul reciproc va fi 1111110111100111, iar codul suplimentar va fi 1111110111101000.

Trebuie amintit că complementul unui număr pozitiv este numărul însuși.

Pentru a stoca numere întregi cu semne altele decât reprezentarea computerului pe 16 biți atunci când este utilizat două registre de memorie(acest format de numere se mai numește și format de număr întreg cu semn scurt), sunt folosite formatele întregi cu semn mediu și lung. Pentru a reprezenta numerele în formatul numărului mijlociu se folosesc patru registre (4 x 8 = 32 de biți), iar pentru a reprezenta numerele în formatul numărului lung se folosesc opt registre (8 x 8 = 64 de biți). Intervalele de valori pentru formatele de număr mediu și lung vor fi, respectiv: -(231 – 1) ... + 231 – 1 și -(263-1) ... + 263 – 1.

Reprezentarea computerizată a numerelor în format punct fix are avantajele și dezavantajele sale. LA beneficii includ simplitatea reprezentării numerelor și algoritmi pentru implementarea operațiilor aritmetice; dezavantajele sunt gama finită de reprezentare a numerelor, care poate fi insuficientă pentru rezolvarea multor probleme de natură practică (matematice, economice, fizice etc.).

Numerele reale (zecimale finite și infinite) sunt procesate și stocate într-un computer în format virgulă mobilă. Cu acest format de reprezentare a numărului, poziția punctului zecimal în intrare se poate modifica. Orice număr real K în format virgulă mobilă poate fi reprezentat ca:

unde A este mantisa numărului; h – baza sistemului de numere; p – ordinea numerelor.

Expresia (2.7) pentru sistemul numeric zecimal va lua forma:

pentru binar -

pentru octal -

pentru hexazecimal -

Această formă de reprezentare a numerelor se mai numește normal . Odată cu schimbarea în ordine, virgula din număr se deplasează, adică pare să plutească spre stânga sau spre dreapta. Prin urmare, se numește forma normală de reprezentare a numerelor formă în virgulă mobilă. Numărul zecimal 15,5, de exemplu, în format virgulă mobilă poate fi reprezentat ca: 0,155 102; 1,55 101; 15,5 100; 155,0 10-1; 1550.0 · 10-2, etc. Această formă de notație zecimală în virgulă mobilă 15.5 nu este utilizată atunci când scrieți programe de calculator și le introduceți într-un computer (dispozitivele de intrare pe computer acceptă doar înregistrarea liniară a datelor). Pe baza acesteia, expresia (2.7) pentru reprezentarea numerelor zecimale și introducerea lor în computer este convertită în forma

unde P este ordinea numărului,

adică, în locul bazei sistemului numeric 10, ei scriu litera E, în loc de virgulă, punct, iar semnul înmulțirii nu este plasat. Astfel, numărul 15,5 în virgulă mobilă și format liniar (reprezentare pe computer) se va scrie ca: 0,155E2; 1,55E1; 15,5E0; 155,0E-1; 1550.0E-2 etc.

Indiferent de sistemul numeric, orice număr sub formă de virgulă mobilă poate fi reprezentat printr-un număr infinit de numere. Această formă de înregistrare se numește nenormalizat . Pentru o reprezentare fără ambiguitate a numerelor în virgulă mobilă, se utilizează o formă normalizată de scriere a unui număr, în care mantisa numărului trebuie să îndeplinească condiția

unde |A| - valoarea absolută a mantisei numărului.

Condiția (2.9) înseamnă că mantisa trebuie să fie o fracție proprie și să aibă o cifră diferită de zero după virgulă, sau, cu alte cuvinte, dacă mantisa nu are un zero după virgulă, atunci numărul se numește normalizat. . Deci, numărul 15,5 în formă normalizată (mantisă normalizată) în formă de virgulă mobilă va arăta astfel: 0,155 102, adică mantisa normalizată va fi A = 0,155 și ordinul P = 2, sau în reprezentarea computerizată a numărului 0,155E2 .

Numerele în virgulă mobilă au un format fix și ocupă patru (32 de biți) sau opt octeți (64 de biți) din memoria computerului. Dacă un număr ocupă 32 de biți în memoria computerului, atunci este un număr obișnuit de precizie; dacă este de 64 de biți, atunci este un număr de precizie dublă. Când se scrie un număr în virgulă mobilă, biții sunt alocați pentru a stoca semnul mantisei, semnul exponentului, mantisei și exponentului. Numărul de cifre alocat ordinii numărului determină gama de variație a numerelor, iar numărul de cifre alocat pentru stocarea mantisei determină precizia cu care este specificat numărul.

Atunci când se efectuează operații aritmetice (adunare și scădere) pe numere prezentate în format virgulă mobilă, se implementează următoarea procedură (algoritm):

1) ordinea numerelor pe care se efectuează operațiile aritmetice este aliniată (ordinea unui număr absolut mai mic crește la ordinea unui număr absolut mai mare, în timp ce mantisa scade cu aceeași cantitate);

2) se efectuează operații aritmetice pe mantisele numerelor;

3) rezultatul obținut este normalizat.

Partea practică