Els reals
Aquesta lliçó explica els valors que poden prendre les variables de
tipus real (double
), com es representen, i quines són les operacions que se’ls
pot aplicar.
El tipus double
En C++, el tipus double
representa el tipus dels nombres reals.
Idealment, double
es correspon al conjunt del reals
($\mathbb{R}$), tot i que, a la pràctica, els ordinadors limiten el nombre real
més petit i més gran assolibles així com la precisió dels reals.
Els valors reals es poden operar amb les operacions habituals
(suma, resta, producte i divisió) i comparar entre ells.
Representació
Els valors reals es representen per literals com ara 3.1416
,
0.001
i -45.0
, és a dir, de la forma habitual. També es pot
utilitzar la notació científica: 21.5e-3
representa $21’5 \cdot
10^{-3}$.
Amb independència de com es representin els nombres reals al codi o a l’entrada/sortida, l’ordinador desa internament els nombres reals utilitzant un determinat nombre de bits en coma flotant $\small[\mathbb{W}]$.
Operacions
Les operacions que es poden aplicar entre dos reals són
la suma (amb l’operador +
),
la resta (amb l’operador -
),
el producte (amb l’operador *
) i
la divisió real (amb l’operador /
).
També hi ha disposible l’operació
de canvi de signe (amb l’operador unari -
).
La operació de residu no existeix per als reals.
La taula següent mostra les operacions bàsiques entre reals:
Operador | Operació |
---|---|
+ |
suma |
- |
resta |
* |
multiplicació |
/ |
divisió real |
- |
canvi de signe |
Les operacions anteriors són les habituals entre reals. Per exemple, 3.5 + 9.0
val 12.5
, 10.0/2.0
val 5.0
, i 11.0/2.0
val 5.5
.
La prioritat dels operadors aritmètics sobre els reals és l’habitual en matemàtiques:
El producte i la divisió tenen prioritat sobre la suma i la resta.
Sempre es poden utilitzar parèntesis per forçar que certes operacions s’apliquin
abans que d’altres. Per exemple, 3.5 + 2.0 * 5.0
val 13.5
però
(3.5 + 2.0) * 5.0
val 35.0
.
A vegades, es barrejen operacions entre enters i reals. En aquests casos, els
enters són convertits de forma automàtica a reals i el resultat és, doncs, un
real. Així 3 + 4.5
es transforma automàticament a 3.0 + 4.5
i el resultat és,
doncs, 7.5
. Compte, 3 + 2.0
dóna com a resultat el real 5.0
i no pas
l’enter 5
.
A més, els reals també es poden comparar entre ells: Donats dos enters, es pot
mirar
si són iguals (amb l’operador ==
),
si són diferents (amb l’operador !=
),
si el primer és estrictament inferior al segon (amb l’operador <
),
si el primer és estrictament superior al segon (amb l’operador >
),
si el primer és inferior o igual al segon (amb l’operador <=
),
i
si el primer és superior o igual al segon (amb l’operador >=
).
La taula següent mostra les operacions bàsiques entre reals:
Operador | Operació |
---|---|
== |
igualtat |
!= |
diferència |
< |
menor |
> |
major |
<= |
menor o igual |
>= |
major o igual |
Problemes de precisió
Com que els computadors emmagatzemen els nombres reals en coma flotant,
aquests no sempre són exactes, sempre són una aproximació prou propera.
Per exemple, el resultat de 0.1 + 0.2
dóna 0.30000000000000004
i ni 0.3
com hom esperaria. I, a sobre, aquests petits errors es propaguen
a través dels càlculs successius!
Conseqüentment, les regles bàsiques de l’àlgebra no sempre es compleixen:
Quan a
i b
són dos doubles, pot ser que a*b != b*a
😩.
Per això, moltes vegades cal que les operacions de comparació entre reals
donin un petit marge de seguretat. Així, per saber si x
i y
són dos reals
iguals, enlloc de preguntar si x == y
, és més prudent preguntar si abs(x -
y) < ε
, on ε
és un valor prou petit (en relació a x
i y
),
com ara 1e-9
(una milionèsima).
Valors especials
Els nombres reals tenen alguns valors “especials” que són pràctics en determinades situacions:
El valor especial +∞ representa l’infinit positiu. És, per exemple, el resultat
de dividir un real positiu entre zero (1.0 / 0.0
). Anàlogament,
el valor especial -∞ representa l’infinit negatiu. És, per exemple, el resultat
de dividir un real negatiu entre zero (-1.0 / 0.0
).
Si es compara un infinit amb un valor finit, el resultat és l’esperat: Per exemple,
1.0 / 0.0 > 99.99
és cert i -1.0 / 0.0 < 1.0 / 0.0
també és cert.
Quan tenen sentit, les operacions amb infinits també es poden aplicar: Per exemple,
5 + 1.0 / 0.0
dóna +∞.
El valor especial NaN (not a number) representa un valor real fruit d’un error.
Per exemple, el resultat de dividir zero entre zero (0.0 / 0.0
) és NaN
i el resultat de sumar +∞ amb -∞ també és NaN (i no zero!). Els valors
NaN no són mai iguals a ells mateixos.
També cal tenir en compte que el zero positiu i el zero negatiu són valors diferents (i el primer és més gran que el segón, és clar).
Confús? Potser sí, però tot està prou ben dissenyat (estàndard IEEE per l’aritmètica en coma flotant $\small[\mathbb{W}]$) i no cal preocupar-se’n massa.
El tipus float
C++ també disposa d’altres tipus per emmagatzemar reals. D’entre ells, sovint
s’utilitza float
, que té menys precisió que double
, però que no és pas més
ràpid en les màquines actuals. A més, a la llibreria estàndard les funcions
solen ser per a double
s i no per a float
s. Per tot això, entre float
i double
us recomanem d’utilitzar double
.
El tipus float
també representa el tipus dels nombres reals, però
en general el tipus double
ofereix més precisió que el tipus float
i és igual de ràpid.
La llibreria <cmath>
La llibreria estàndard <cmath>
sèrie de funcions
matemàtiques sobre nombres reals com ara arrels quadrades, valors absoluts,…
que extenen els operadors descrits. També defineix la funció
isnan()
per saber si
un real és NaN.
La llibreria <limits>
La llibreria estàndard <limits>
ofereix funcions que poden ser útils a
l’hora de treballar amb nombres reals:
numeric_limits<double>::infinity()
retorna el valor infinit pelsdouble
s.numeric_limits<double>::max()
retorna el valor finit més gran pelsdouble
s.numeric_limits<double>::min()
retorna el valor finit més petit pelsdouble
s.
També es poden utilitzar per float
s.
Lliçons.jutge.org
Jordi Petit, Salvador Roura
Universitat Politècnica de Catalunya, 2023
Prohibit copiar. Tots els drets reservats.
No copy allowed. All rights reserved.