Main Content

La traducción de esta página aún no se ha actualizado a la versión más reciente. Haga clic aquí para ver la última versión en inglés.

Números de punto flotante

MATLAB® representa números de punto flotante en formato de doble precisión o en formato de precisión simple. El formato predeterminado es el de doble precisión, pero puede pasar cualquier número a formato de precisión simple con una función sencilla de conversión.

Punto flotante de doble precisión

MATLAB construye el tipo de datos de doble precisión (o double) de acuerdo con el estándar 754 del IEEE® para doble precisión. Cualquier valor almacenado como un double requiere 64 bits, con formato como se muestra en la siguiente tabla:

Bits

Uso

63

Signo (0 = positivo, 1 = negativo)

62 a 52

Exponente, sesgado por 1023

51 a 0

Fracción f del número 1.f

Punto flotante de precisión simple

MATLAB construye el tipo de datos de precisión simple (o single) de acuerdo con el estándar 754 del IEEE para precisión simple. Cualquier valor almacenado como un single requiere 32 bits, con formato como se muestra en la siguiente tabla:

Bits

Uso

31

Signo (0 = positivo, 1 = negativo)

30 a 23

Exponente, sesgado por 127

22 a 0

Fracción f del número 1.f

Dado que MATLAB almacena números de tipo single usando 32 bits, requieren menos memoria que los números de tipo double, que utilizan 64 bits. Sin embargo, dado que los números de tipo single se almacenan con menos bits, se representan con menos precisión que los números de tipo double.

Crear datos de punto flotante

Utilice la doble precisión para almacenar valores mayores que aproximadamente 3,4 x 1038 o menores que aproximadamente -3,4 x 1038. Para números que se encuentren entre estos dos límites, puede utilizar o bien la doble precisión o bien la precisión simple, pero la precisión simple requiere menos memoria.

Crear datos de doble precisión

Dado que el tipo numérico predeterminado para MATLAB es double, puede crear un double con una instrucción sencilla de asignación:

x = 25.783;

La función whos muestra que MATLAB ha creado un arreglo de 1 por 1 de tipo double para el valor que acaba de almacenar en x:

whos x
  Name      Size                   Bytes  Class

  x         1x1                        8  double

Utilice isfloat si solo desea verificar que x es un número de punto flotante. Esta función devuelve un 1 lógico (true) si la entrada es un número de punto flotante y un 0 lógico (false) si no lo es:

isfloat(x)
ans =

  logical

   1

Puede convertir otros datos numéricos, caracteres o cadenas, y datos lógicos a doble precisión mediante la función double de MATLAB. En este ejemplo se convierte un entero con signo a punto flotante de doble precisión:

y = int64(-589324077574);          % Create a 64-bit integer

x = double(y)                      % Convert to double
x =
  -5.8932e+11

Crear datos de precisión simple

Dado que MATLAB almacena datos numéricos como un double de forma predeterminada, debe utilizar la función de conversión single para crear un número de precisión simple:

x = single(25.783);

La función whos devuelve los atributos de la variable x en una estructura. El campo bytes de esta estructura muestra que cuando se almacena x como un simple, solo hacen falta 4 bytes en comparación con los 8 bytes necesarios para almacenarlo como un double.

xAttrib = whos('x');
xAttrib.bytes
ans =
     4

Puede convertir otros datos numéricos, caracteres o cadenas, y datos lógicos a precisión simple mediante la función single. En este ejemplo se convierte un entero con signo a punto flotante de precisión simple:

y = int64(-589324077574);          % Create a 64-bit integer

x = single(y)                      % Convert to single
x =

  single

 -5.8932e+11

Operaciones aritméticas en números de punto flotante

En esta sección se describe qué clases puede utilizar en las operaciones aritméticas con números de punto flotante.

Operaciones de doble precisión

Puede realizar operaciones aritméticas básicas con double y cualquiera de las siguientes otras clases. Cuando uno o más operandos son un entero (escalar o arreglo), el operando double debe ser un escalar. El resultado es de tipo double, salvo cuando se observe lo contrario:

  • single: el resultado es de tipo single

  • double

  • int* o uint*: el resultado tiene el mismo tipo de datos que el operando de enteros

  • char

  • logical

En este ejemplo se realizan operaciones aritméticas con datos de tipo char y double. El resultado es de tipo double:

c = 'uppercase' - 32;

class(c)
ans =
   double

char(c)
ans =
   UPPERCASE

Operaciones de precisión simple

Puede realizar operaciones aritméticas básicas con single y cualquiera de las siguientes otras clases. El resultado siempre es single:

  • single

  • double

  • char

  • logical

En este ejemplo, de forma predeterminada, 7.5 es de tipo double y el resultado es de tipo single:

x = single([1.32 3.47 5.28]) .* 7.5;

class(x)
ans =
   single

Los valores más grandes y más pequeños para clases de punto flotante

Para las clases double y single, existe el número más grande y más pequeño que puede representar con ese tipo.

Los valores de doble precisión más grande y más pequeño

Las funciones de MATLAB realmax y realmin devuelven los valores máximos y mínimos que puede representar con el tipo de datos double:

str = 'The range for double is:\n\t%g to %g and\n\t %g to  %g';
sprintf(str, -realmax, -realmin, realmin, realmax)

ans =
The range for double is:
   -1.79769e+308 to -2.22507e-308 and
    2.22507e-308 to  1.79769e+308

A los números mayores que realmax o menores que -realmax se les asignan los valores de infinito positivo y negativo, respectivamente:

realmax + .0001e+308
ans =
   Inf

-realmax - .0001e+308
ans =
  -Inf

Los valores de precisión simple más grande y más pequeño

Las funciones de MATLAB realmax y realmin, cuando se llaman con el argumento 'single', devuelven los valores máximo y mínimo que puede representar con el tipo de datos single:

str = 'The range for single is:\n\t%g to %g and\n\t %g to  %g';
sprintf(str, -realmax('single'), -realmin('single'), ...
    realmin('single'), realmax('single'))

ans =
The range for single is:
	-3.40282e+38 to -1.17549e-38 and
	 1.17549e-38 to  3.40282e+38

A los números mayores que realmax('single') o menores que -realmax('single') se les asignan los valores de infinito positivo y negativo, respectivamente:

realmax('single') + .0001e+038
ans =

  single

   Inf

-realmax('single') - .0001e+038
ans =

  single

  -Inf

Precisión de los datos de punto flotante

Si el resultado de un cálculo aritmético de punto flotante no es tan preciso como esperaba, es posible que se deba a las limitaciones de hardware de su equipo. Probablemente, el resultado sea un poco menos exacto porque el hardware no disponía de los suficientes bits para representar el resultado con una precisión perfecta. Por lo tanto, el valor resultante se ha truncado.

Precisión en doble precisión

Dado que existe solo un número finito de números de doble precisión, no puede representar todos los números en el almacenamiento de doble precisión. En cualquier ordenador, existe un pequeño vacío entre cada número de doble precisión y el siguiente número de doble precisión mayor. Puede determinar el tamaño de este vacío que limita la precisión de los resultados con la función eps. Por ejemplo, para encontrar la distancia entre 5 y el siguiente número de doble precisión mayor, introduzca

format long

eps(5)
ans =
     8.881784197001252e-16

Esto indica que no existen números de doble precisión entre 5 y 5 + eps(5). Si el cálculo de doble precisión devuelve la respuesta 5, el resultado solo es preciso dentro de eps(5).

El valor de eps(x) depende de x. En este ejemplo se muestra que, a medida que x se hace más grande, también lo hace eps(x):

eps(50)
ans =
     7.105427357601002e-15

Si introduce eps sin argumento de entrada, MATLAB devuelve el valor de eps(1), la distancia desde 1 hasta el siguiente número de doble precisión mayor.

Precisión en precisión simple

De forma similar, existen vacíos entre dos números de precisión simple cualesquiera. Si x tiene el tipo single, eps(x) devuelve la distancia entre x y el siguiente número de precisión simple mayor. Por ejemplo:

x = single(5);
eps(x)

devuelve

ans =

  single

  4.7684e-07

Observe que este resultado es mayor que eps(5). Dado que existen menos números de precisión simple que de doble precisión, los vacíos entre los números de precisión simple son mayores que los vacíos entre los números de doble precisión. Esto significa que los resultados de las operaciones aritméticas de precisión simple son menos precisos que los de las operaciones aritméticas de doble precisión.

Para un número x de tipo double, eps(single(x)) proporciona un límite superior para la cantidad con la que se redondea x cuando se convierte de double a single. Por ejemplo, cuando convierte el número de doble precisión 3.14 a single, se redondea con

double(single(3.14) - 3.14)
ans =
   1.0490e-07

La cantidad con la que 3.14 se redondea es inferior a

eps(single(3.14))
ans =

  single

  2.3842e-07

Evitar problemas habituales con las operaciones aritméticas de punto flotante

Casi todas las operaciones en MATLAB se realizan con operaciones aritméticas de doble precisión, de acuerdo con el estándar 754 del IEEE. Dado que los ordenadores solo representan los números con una precisión finita (la doble precisión requiere 52 bits de mantisa), en ocasiones los cálculos producen resultados no intuitivos desde el punto de vista matemático. Es importante tener en cuenta que estos resultados no son bugs en MATLAB.

Utilice los siguientes ejemplos para ayudarle a identificar estos casos:

Ejemplo 1. Redondeo o lo que se obtiene no es lo que se espera

El número decimal 4/3 no se puede representar de manera exacta como una fracción binaria. Por esta razón, el siguiente cálculo no da cero, sino que revela la cantidad eps.

e = 1 - 3*(4/3 - 1)

e =
   2.2204e-16

De manera similar, 0.1 no se puede representar de manera exacta como un número binario. Por tanto, obtiene el siguiente comportamiento no intuitivo:

a = 0.0;
for i = 1:10
  a = a + 0.1;
end
a == 1
ans =

  logical

   0

Tenga en cuenta que el orden de las operaciones puede influir en el cálculo:

b = 1e-16 + 1 - 1e-16;
c = 1e-16 - 1e-16 + 1;
b == c
ans =

  logical

   0

Existen vacíos entre números de punto flotante. A medida que los números se hacen mayores, también lo hacen los vacíos, como demuestra:

(2^53 + 1) - 2^53

ans =
     0

Dado que pi no es realmente π, no resulta sorprendente que sin(pi) no sea exactamente cero:

sin(pi)

ans =
     1.224646799147353e-16

Ejemplo 2. Cancelación catastrófica

Cuando se realizan restas con operandos casi iguales, en ocasiones puede producirse una cancelación de forma inesperada. A continuación, figura un ejemplo de una cancelación causada por empantanamiento (pérdida de precisión que hace que la suma sea insignificante).

sqrt(1e-16 + 1) - 1

ans =
     0

Algunas funciones de MATLAB, como expm1 y log1p, pueden utilizarse para compensar los efectos de una cancelación catastrófica.

Ejemplo 3. Operaciones de punto flotante y álgebra lineal

Redondeos, cancelaciones y otras cualidades de las operaciones aritméticas de punto flotante se combinan para producir cálculos sorprendentes cuando se resuelven problemas de álgebra lineal. MATLAB advierte de que la siguiente matriz A está mal condicionada y, por lo tanto, el sistema Ax = b puede ser susceptible a pequeñas perturbaciones:

A = diag([2 eps]); 
b = [2; eps]; 
y = A\b; 
Warning: Matrix is close to singular or badly scaled.
         Results may be inaccurate. RCOND = 1.110223e-16.

Estos son tan solo algunos de los ejemplos que muestran cómo las operaciones aritméticas de punto flotante del IEEE afectan a los cálculos en MATLAB. Tenga en cuenta que todos los cálculos realizados en operaciones aritméticas de acuerdo con el estándar 754 del IEEE se ven afectados. Esto incluye las aplicaciones escritas en C o FORTRAN, así como MATLAB.

Referencias

[1] Moler, Cleve. “Floating Points.” MATLAB News and Notes. Fall, 1996.

[2] Moler, Cleve. Numerical Computing with MATLAB. Natick, MA: The MathWorks, Inc., 2004.