Coma flotant

De Viquipèdia
Dreceres ràpides: navegació, cerca

Coma flotant o punt flotant és un mètode de representació aproximada de nombres reals que es pot adaptar a l'ordre de magnitud del valor a representar, usualment traslladant la coma decimal - mitjançant un exponent - cap a la posició de la primera xifra significativa del valor.

D'aquesta forma, amb un nombre donat de dígits representatius s'obté major precisió del que amb la coma fixa, a causa que el valor d'aquests dígits és sempre significatiu sigui el que sigui l'ordre de magnitud del nombre a representar. A causa d'aquesta adaptació, permet representar un rang molt més gran de nombres (determinat pels valors límit que pot prendre l'exponent).

El seu ús és especialment interessant en la informàtica, ja que permet treballar amb nombres decimals en rangs amplis, encara que també s'usa el truncat de decimals.

Representació[modifica | modifica el codi]

Representació binària de nombres en coma flotant de doble precisió.

Una representació en coma flotant es compon de tres nombres (camps) que segueixen el següent patró:

r=m . b^e

r: valor real del nombre a representar
m: mantissa o significant, dígits significatius del nombre. La mida màxima d'aquest camp, usualment fix i limitat, determina la precisió de la representació. Aquest camp està usualment normalitzat, és a dir, la seva part sencera només consta d'un dígit (que serà la primera xifra significativa del nombre a representar).
b: base del sistema de representació (10 en sistema decimal, 8 en sistema octal, 2 en sistema binari, etc.)
e: exponent, ordre de magnitud del significant. El mínim i màxim valor possible de l'exponent determinen el rang de valors representables. Es pot afegir que quan e val zero el valor real coincideix amb el significant.

En certs casos s'usa com r=s \cdot m \cdot b^e, amb un quarta mantissa, s, que té el valor d'1 o -1 segons el signe del nombre (que s'extreu del significant).

Exemples de com canvia un nombre al variar l'exponent de la base:

  • 2,71828 x 10-2 representa el nombre real 0,0271828
  • 2,71828 x 10-1 representa el nombre real 0,271828
  • 2,71828 x 100 representa el nombre real 2,71828 (l'exponent 0 indica que la coma no es desplaça)
  • 2,71828 x 101 representa el nombre real 27,1828
  • 2,71828 x 102 representa el nombre real 271,828

Sistema decimal[modifica | modifica el codi]

Article principal: Notació científica

Amb la finalitat d'optimitzar la notació de xifres de nombrosos dígits, s'acudeix a l'ús d'unitats múltiples en el cas de ser un valor mètric o a la coma flotant en els altres. El seu ús és comú en la física pels valors amplis i imprecisos que s'acostumen a obtenir. Per aquesta raó també s'inclou certa permissivitat amb la inexactitud del valor. L'error que pot sorgir de l'ocupació d'aquest mètode se sol combinar a l'error calculat dels resultats.

El mètode utilitzat és moure la coma a la part més significativa de la xifra, és a dir, variant el pes aritmètic dels dígits que ho componen. Per a entendre el significat dels nombres en coma flotant, acudim a exemples més evidents del sistema decimal:

  • Suposem que tenim els següents nombres reals: 3135,07; 0,04576 i 69233704,063.
  • Prenent d'aquests els seus 6 dígits significatius, la seva conversió a notació de coma flotant normalitzada, en on la coma decimal se situa a la dreta del primer dígit, s'escriuran 3,13507×10^3; 4,57600×10^-2 i 6,92337×10^7.

Com s'observa en aquests exemples, la coma decimal s'ha desplaçat cap a la dreta o cap a l'esquerra per a obtenir la mateixa estructura en la notació. La pèrdua d'informació en el tercer cas és potencialment negligible, el seu error és del 0,001%.

En notació de coma fixa, amb 4 dígits per als sencers i 2 dígits, per als decimals s'obtindria 3135,07; 0,04 i 3704,06 podent perdre informació important en entorns no controlats d'ús.

Sistema binari[modifica | modifica el codi]

Article principal: Codi binari

Un valor real es pot estendre a l'esquerra o a la dreta de forma arbitrària. En la informàtica es disposa d'una quantitat limitada de dígits per a representar un valor, un nombre real pot rebaixar aquest rang amb facilitat. La coma flotant proporciona un canvi de ponderació que en aquest entorn tècnic permet emmagatzemar valors amb parts significatives de pes allunyat a 0, això és allunyades de la coma a la seva dreta o a la seva esquerra. La limitació es troba quan existeix informació de pes molt menor al de la part significativa que és necessàriament truncat. No obstant això, i segons l'ús, la rellevància d'aquestes dades pot ser menyspreada, raó per la qual el mètode és interessant malgrat ser una potencial font d'error.

Tècnicament no es pot col·locar una coma en una xifra, ja que només es poden manejar valors de 0 i 1. Per a resoldre el problema es força que la mantissa estigui normalitzada, amb la qual cosa es coneix la posició de la coma.

El bit de major pes defineix si hi ha signe negatiu o no ho hi ha. Li segueixen una sèrie de bits que defineixen l'exponent en defecte a la meitat del rang de dits bits. La resta de bits són la mantissa.

Emprarem diversos exemples en una notació de 16 bits per a descriure el mètode usat:


\begin{matrix} s\\ \overbrace{ 1 } \\ 0 \\ 0 \end{matrix} \quad
\begin{matrix} e\\ \overbrace{ 100011 } \\ 011011 \\ 101001 \end{matrix} \quad
\begin{matrix} m\\ \overbrace{ 011101100 } \\ 111001101 \\ 000000001 \end{matrix}
\begin{matrix} \ \\ \quad = \mathrm{0xC6EC} \\ \quad = \mathrm{0x37CD} \\ \ = \mathrm{0x5201} \end{matrix}

En aquest cas, l'exponent ocupa 6 bits capaços de representar de 0 a 63, per tant, a l'exponent se li suma 31 en aquesta notació. La mantissa, al ser normalitzada, tindrà sempre un 1 en la seva part sencera. Aquest bit redundant es denomina bit ocult o implícit i no s'inclou en aquesta notació.

La notació genèrica esmentada a dalt per a la coma flotant és així respectivament: -1 \times \mathit 1,011101100 \times 10^{100} = 10111,01100

1 \times \mathit 1,111001101 \times 10^{-1110} = 0,00000000000001111001101

1 \times \mathit 1,000000001 \times 10^{1010} = 10000000010

(amb tots els valors expressats en representació binària)

La notació en coma flotant és més lenta de processar i menys precisa que la notació en coma fixa, però donat una grandària fixa de dígits, permet un major rang en els nombres que es poden representar amb ells.

Com que les operacions aritmèticas que es realitzen amb nombres en coma flotant són molt complexes de realitzar, molts sistemes destinen un processador especial per a la realització específica d'aquest tipus d'operacions, denominat FPU (Floating Point Unit) o Unitat de Coma Flotant.

En ordinadors i calculadores els nombres en coma flotant se solen representar de forma distinta. On s'hauria d'escriure m \times b^e \,\! se sol escriure m\mathrm{E}e \,\! (per exemple 1.857252E06 \,\!, també escrit 1.857252E06 \,\! i 1.857252E+06 \,\!; un altre exemple: 1.857252E-06 \,\!) o fins i tot, sobretot en calculadores científiques: m^b \,\!, encara que tècnicament és incorrecte (per exemple 9.856723 ^ {48} \,\!).

Nombres de coma flotant als ordinadors[modifica | modifica el codi]

En el cas dels ordinadors és necessari que el sistema numèric sigui el més fiable possible. S'ha de considerar que el conjunt de nombres en coma flotant és un subconjunt finit dels nombres racionals amb el qual es pretén representar al conjunt infinit dels nombres reals. Inclús, si l'ordinador realitza una operació invàlida, el resultat que es guarda al registre ha de ser adequat, raó per la qual es requereix d'algunes representacions especials. Això significa que cada nombre de coma flotant "x" representa un interval real.

La norma IEEE 754 especifica els requeriments mínims que un sistema en coma flotant ha de tenir, unificant els formats numèrics entre dissenyadors de llenguatges, desenvolupadors de compiladors i fabricants de processadors. Independentment dels paràmetres particulars que la norma 754 de IEEE especifica per a la seva implementació és possible estudiar les propietats dels nombres en coma flotant de manera més general.

Tipus de dades en coma flotant[modifica | modifica el codi]

Els nombres en coma flotant, també coneguts com nombres reals en altres llenguatges, s'utilitzen quan es calculen funcions que requereixen precisió fraccionaria. Els càlculs complexes, l'arrel quadrada o funcions trigonomètrics, com el sinus i el cosinus, tenen com ha resultat un valor el qual la precisió requereix un tipus en coma flotant. Hi ha dos classes de tipus en coma flotant: float i double.[1]


Tipus Mida Rang 
------------------------------------------------------
float 4 bytes (32 bits) 3.4e-038..3.4e+038
double 8 bytes (64 bits) 1.7e-308..1.7e+308


Operacions aritmètiques amb coma flotant[modifica | modifica el codi]

Per facilitar la presentació i la comprensió, decimal amb 7 dígits de precisió, s'utilitzarà en els exemples, com en l'estàndard IEEE 754 en format decimal32. Els principis fonamentals són els mateixos en qualsevol base o de la precisió, llevat de la normalització que és opcional. En aquest cas, s denota la mantissa i e, indica l'exponent.

Suma i resta[modifica | modifica el codi]

Un mètode simple per afegir nombres de coma flotant és primer representen amb el mateix exponent. En el següent exemple, el segon nombre es desplaça a la dreta tres dígits, i després procedir amb el mètode de suma de sempre:

123456,7 = 1,234567 * 10^5
101.7654 = 1.017654 * 10^2 = 0,001017654 * 10^5
Per tant:
123456,7 + 101,7654 = (1,234567 * 10^5) + (1,017654 * 10^2)
= (1.234567 * 10 ^ 5) + (0,001017654 * 10^5)
= (1.234567 + 0,001017654) * 10^5
= 1.235584654 * 10^5

En detall:

E = 5; s = 1.234567 (123.456,7)
+ E = 2; s = 1,017654 (101,7654)
E = 5; s = 1,234567
+ E = 5; s = 0,001017654 (després de desplaçar)
--------------------
E = 5; s = 1,235584654 (suma : 123558.4654)

Aquest és el veritable resultat, la suma exacta dels operands serà arrodonit a set dígits i, a continuació normalitzada si és necessari. El resultat final és

E = 5; s = 1.235585 (suma final: 123.558,5)

Tingueu en compte que al desplaçar 3 dígits del segon operand (654) són perdut. Aquesta és la error d'arrodoniment. En casos extrems, la suma de dos nombres zero no pot ser igual a un d'ells:

E = 5; s = 1,234567
+ E =- 3, s = 9,876543
E = 5; s = 1,234567
+ E = 5; s = 0,00000009876543 (després de desplaçar)
----------------------
E = 5; s = 1,23456709876543 (suma veritable)
E = 5; s = 1.234567 (després d'arrodonir / normalització)

Un altre problema de la pèrdua d'importància es produeix quan es resten dos nombres pròxims. En el següent exemple e= 5;s= 1,234571 ie= 5;s= 1.234567 són representacions dels racionals 123457.1467 i 123.456,659.

E = 5; s = 1,234571
- E = 5; s = 1,234567
----------------
E = 5; s = 0,000004
i =- 1; s = 4.000000 (després d'arrodonir / normalització)

La millor representació d'aquesta diferència és e= -1; s= 4,877000, que difereix més del 20% de la e= -- 1; s= 4,000000. En casos extrems, el resultat final pot ser zero milions, encara que un càlcul exacte pot variar. Aquesta Cancel·lació il·lustra el perill de suposar que tots els dígits d'un resultat calculat són significatius. Davant les conseqüències d'aquests errors és un tema en anàlisi numèrica, veure també problemes de precisió.

L'estàndard exigeix que el resultat de les operacions sigui el mateix que el que s'obtindria si es fessin amb precisió absoluta i després s'arrodonís el resultat. Una de les tècniques seria utilitzar dígits addicionals per mantenir la precisió.

Multiplicació[modifica | modifica el codi]

Per multiplicar, es multipliquen les mantisses mentre que els exponents se sumen i el resultat s'arrodoneix i normalitzada.

E = 3; s = 4,734612
× E = 5; s = 5,417242
-----------------------
E = 8; s producte = 25.648538980104 (true)
E = 8; s = 25,64854 (després d'arrodonir)
E = 9; s = 2.564854 (després de la normalització)

Divisió es realitza de manera similar, però és més complicat.

No hi ha cancel·lació o l'absorció dels problemes amb la multiplicació o divisió, tot i petits que errors són acomulatius, com les operacions es realitzen en diverses ocasions. A la pràctica, la forma en què aquestes operacions es duguin a terme a la lògica digital pot ser molt complexa (veure algorisme de la multiplicació de Booth i divisió digital).[2]

Infinits[modifica | modifica el codi]

Els Infinits de la Recta Real es poden representar amb els tipus de dades de coma flotant de l'IEEE igual que qualsevol altre valor de punt flotant com 1, 1.5 etc. No son valors d'error, encara que sovint (però no sempre, depèn de l'arrodoniment) s'usen com valors de retorn quan hi ha un overflow. En el cas d'una divisió per zero es retorna unn infinit positiu o negatiu com a resultat. Un infinit també pot ser introduït com qualsevol nombre (a C amb la macro "INFINITY", per exemple, o "∞" si el llenguatge de programació permet aquesta sintaxi).

L'IEEE 754 requereix que els infinits es puguin operar com qualsevol altre nombre, per exemple:

  • (+∞) + (+7) = (+∞)
  • (+∞) × (−2) = (−∞)
  • (+∞) × 0 = NaN – el resultat no es pot interpretar.

NaNs[modifica | modifica el codi]

En IEEE 754 hi ha certs valors anoments "Not a Number" (NaN), valors que sorgeixen de certes operacions invàlides com ara 0/0, ∞×0, o sqrt(−1). Hi ha dos tipus de NaN: en anglès s'anomenen "signaling"(generen una excepció quan s'utilitzen en operacions aritmètiques) i "quiet(simplement mostren el resultat)". La representació d'aquests nombres a l'IEEE 754 contenen certs bits sense especificar que es poden utilitzar per codificar el tipus error.

Referències[modifica | modifica el codi]

  1. «Reals(IV): Coma flotant (representació)» (PDF). Universitat de Girona. [Consulta: 05-03-2010].
  2. L'enorme complexitat dels algorismes de la divisió moderna ha comportat errors de famosos: una primera versió del xip Pentium d'Intel fou enviada amb una instrucció de divisió que, en rares ocasions, va donar resultats lleugerament incorrectes. Com que molts equips s'havien enviat abans que es descobrir l'error, fins que van ser reemplaçats els equips defectuosos, van implementar actualitzacions dels compiladors per tal d'evitar els casos que fallen. Vegeu Error de divisió del Pentium.

Vegeu també[modifica | modifica el codi]

Enllaços externs[modifica | modifica el codi]