Números de punto flotante
"Punto flotante" se refiere a un conjunto de tipos de datos que codifican números reales, incluidas fracciones y decimales. Los tipos de datos de punto flotante permiten un número distinto de dígitos después del punto decimal, mientras que los tipos de datos de punto fijo tienen un número determinado de dígitos reservado antes y después del punto decimal. Por lo tanto, los tipos de datos de punto flotante pueden representar una mayor variedad de números que los tipos de datos de punto fijo.
Debido a la memoria limitada para representar y almacenar números, los ordenadores pueden representar un conjunto finito de números de punto flotante que tienen precisión finita. Esta precisión finita puede limitar la precisión de los cálculos de punto flotante que requieren valores exactos o una gran precisión, ya que algunos números no se representan de manera exacta. A pesar de sus limitaciones, los números de punto flotante se usan mucho debido a sus cálculos rápidos y a su precisión e intervalo suficientes para resolver problemas del mundo real.
Números de punto flotante en MATLAB
MATLAB® tiene tipos de datos para números de punto flotante de doble precisión (double
) y precisión simple (single
) de conformidad con el estándar 754 del IEEE®. De forma predeterminada, MATLAB representa los números de punto flotante en formato de doble precisión. La doble precisión permite representar números con mayor precisión, pero requiere más memoria que la precisión simple. Para ahorrar memoria, puede convertir un número a precisión simple utilizando la función single
.
Puede almacenar números entre aproximadamente –3,4 × 1038 y 3,4 × 1038 utilizando la doble precisión o la precisión simple. Si tiene números fuera de ese intervalo, almacénelos usando la doble precisión.
Crear datos de doble precisión
Dado que el tipo numérico predeterminado para MATLAB es el tipo double
, puede crear un número de punto flotante de doble precisión con una sencilla instrucción de asignación.
x = 10; c = class(x)
c = 'double'
Puede convertir datos numéricos, caracteres o cadenas, y datos lógicos a doble precisión usando la función double
. Por ejemplo, convierta un entero con signo a un número de punto flotante de doble precisión.
x = int8(-113); y = double(x)
y = -113
Crear datos de precisión simple
Para crear un número de precisión simple, utilice la función single
.
x = single(25.783);
También puede convertir datos numéricos, caracteres o cadenas, y datos lógicos a precisión simple usando la función single
. Por ejemplo, convierta un entero con signo a un número de punto flotante de precisión simple.
x = int8(-113); y = single(x)
y = single -113
Cómo almacena MATLAB números de punto flotante
MATLAB construye sus tipos de datos de punto flotante double
y single
de acuerdo con el formato del IEEE y sigue el modo de redondeo redondeo al más próximo con desempate al par de forma predeterminada.
Un número de punto flotante x tiene la forma:
donde:
s determina el signo.
f es la fracción, o mantisa, que cumple 0 ≤ f < 1.
es el exponente.
s, f y e están determinados cada uno por un número finito de bits en memoria, dependiendo f y e de la precisión del tipo de datos.
El almacenamiento de un número double
requiere 64 bits, tal como se muestra en esta tabla.
Bits | Ancho | Uso |
---|---|---|
63 | 1 | Almacena el signo, donde 0 es positivo y 1 es negativo |
62 a 52 | 11 | Almacena el exponente, sesgado por 1023 |
51 a 0 | 52 | Almacena la mantisa |
El almacenamiento de un número single
requiere 32 bits, tal como se muestra en esta tabla.
Bits | Ancho | Uso |
---|---|---|
31 | 1 | Almacena el signo, donde 0 es positivo y 1 es negativo |
30 a 23 | 8 | Almacena el exponente, sesgado por 127 |
22 a 0 | 23 | Almacena la mantisa |
Valores más grandes y más pequeños para tipos de datos de punto flotante
Los tipos de datos de doble precisión y de precisión simple tienen un valor más grande y más pequeño que se puede representar. A los números fuera del intervalo representable se les asigna infinito positivo o negativo. Sin embargo, algunos números dentro del intervalo representable no se pueden almacenar de manera exacta debido a los vacíos entre números de punto flotante consecutivos, y estos números pueden tener errores de redondeo.
Valores de doble precisión más grandes y más pequeños
Busque los valores positivos más grandes y más pequeños que pueden representarse con el tipo de datos double
usando las funciones realmax
y realmin
, respectivamente.
m = realmax
m = 1.7977e+308
n = realmin
n = 2.2251e-308
realmax
y realmin
devuelven valores normalizados del IEEE. Puede encontrar los valores negativos más grandes y más pequeños multiplicando realmax
y realmin
por -1
. A los números mayores que realmax
o menores que –realmax
se les asignan los valores de infinito positivo o negativo, respectivamente.
Valores de precisión simple más grandes y más pequeños
Busque los valores positivos más grandes y más pequeños que pueden representarse con el tipo de datos single
llamando a las funciones realmax
y realmin
con el argumento "single"
.
m = realmax("single")
m = single 3.4028e+38
n = realmin("single")
n = single 1.1755e-38
Puede encontrar los valores negativos más grandes y más pequeños multiplicando realmax("single")
y realmin("single")
por –1
. A los números mayores que realmax("single")
o menores que –realmax("single")
se les asignan los valores de infinito positivo o negativo, respectivamente.
Enteros de punto flotante consecutivos más grandes
No todos los enteros se pueden representar usando tipos de datos de punto flotante. El entero consecutivo más grande, x, es el entero más grande para el que todos los enteros menores que o iguales a x pueden representarse de manera exacta, pero x + 1 no se puede representar en formato de punto flotante. La función flintmax
devuelve el entero consecutivo más grande. Por ejemplo, busque el entero consecutivo más grande en formato de punto flotante de doble precisión, que es 253, usando la función flintmax
.
x = flintmax
x = 9.0072e+15
Busque el entero consecutivo más grande en formato de punto flotante de precisión simple, que es 224.
y = flintmax("single")
y = single 16777216
Cuando convierte un tipo de datos enteros a un tipo de datos de punto flotante, los enteros que no se pueden representar de manera exacta en formato de punto flotante pierden precisión. flintmax
, que es un número de punto flotante, es menor que el mayor entero que se puede representar por tipos de datos enteros usando el mismo número de bits. Por ejemplo, flintmax
para doble precisión es 253, mientras que el valor máximo para el tipo int64
es 264 – 1. Por tanto, convertir un entero mayor que 253 a formato de doble precisión tiene como resultado una pérdida de precisión.
Precisión de los datos de punto flotante
La precisión de los datos de punto flotante puede verse afectada por varios factores:
Limitaciones del hardware del ordenador: por ejemplo, un hardware con memoria insuficiente trunca los resultados de los cálculos de punto flotante.
Los vacíos entre cada número de punto flotante y el siguiente número de punto flotante mayor: estos vacíos están presentes en cualquier ordenador y limitan la precisión.
Vacíos entre números de punto flotante
Puede determinar el tamaño de un vacío entre números de punto flotante consecutivos usando la función eps
. Por ejemplo, busque la distancia entre 5
y el siguiente número de doble precisión mayor.
e = eps(5)
e = 8.8818e-16
No puede representar números entre 5
y 5 + eps(5)
en formato de doble precisión. Si un cálculo de doble precisión devuelve la respuesta 5
, el resultado es preciso dentro de eps(5)
. Este radio de precisión a menudo se llama épsilon de la máquina.
Los vacíos entre números de punto flotante no son iguales. Por ejemplo, el vacío entre 1e10
y el siguiente número de doble precisión mayor es superior al vacío entre 5
y el siguiente número de doble precisión mayor.
e = eps(1e10)
e = 1.9073e-06
De forma similar, busque la distancia desde 5
y el siguiente número de precisión simple mayor.
x = single(5); e = eps(x)
e = single 4.7684e-07
Los vacíos entre números de precisión simple son mayores que los vacíos entre números de doble precisión porque hay menos números de precisión simple. Por lo tanto, los resultados de los cálculos de precisión simple son menos precisos que los resultados de los cálculos de doble precisión.
Cuando se convierte un número de doble precisión a un número de precisión simple, se puede determinar el límite superior para la cantidad a la que se redondea el número usando la función eps
. Por ejemplo, cuando convierte el número de doble precisión 3.14
a precisión simple, el número se redondea a eps(single(3.14))
como máximo.
Vacíos entre enteros de punto flotante consecutivos
La función flintmax
devuelve el entero consecutivo más grande en formato de punto flotante. Por encima de este valor, los enteros de punto flotante consecutivos tienen un vacío mayor que 1
.
Busque el vacío entre flintmax
y el siguiente número de punto flotante usando eps
:
format long
x = flintmax
x = 9.007199254740992e+15
e = eps(x)
e = 2
Dado que eps(x)
es 2
, el siguiente número de punto flotante mayor que se puede representar de manera exacta es x + 2
.
y = x + e
y = 9.007199254740994e+15
Si añade 1
a x
, el resultado se redondea a x
.
z = x + 1
z = 9.007199254740992e+15
Operaciones aritméticas en números de punto flotante
Puede usar un intervalo de tipos de datos en operaciones aritméticas con números de punto flotante, y el tipo de datos del resultado depende de los tipos de entrada. Sin embargo, cuando realiza operaciones con diferentes tipos de datos, es posible que algunos cálculos no sean exactos debido a las aproximaciones o las conversiones intermedias.
Operandos de doble precisión
Puede realizar operaciones aritméticas básicas con double
y cualquiera de los siguientes tipos de datos. Si uno o más operandos son un escalar o un arreglo de enteros, el operando double
debe ser un escalar. El resultado es de tipo double
, salvo cuando se especifique lo contrario.
single
: el resultado es de tiposingle
.double
int8
,int16
,int32
,int64
: el resultado tiene el mismo tipo de datos que el operando de enteros.uint8
,uint16
,uint32
,uint64
: el resultado tiene el mismo tipo de datos que el operando de enteros.char
logical
Operandos de precisión simple
Puede realizar operaciones aritméticas básicas con single
y cualquiera de los siguientes tipos de datos. El resultado es de tipo single
.
single
double
char
logical
Resultados inesperados con operaciones aritméticas de punto flotante
Casi todas las operaciones en MATLAB se realizan con operaciones aritméticas de doble precisión de conformidad con el estándar 754 del IEEE. Dado que los ordenadores representan números con una precisión finita, algunos cálculos pueden generar resultados no intuitivos desde el punto de vista matemático. Algunos problemas habituales que pueden surgir mientras se realizan cálculos con números de punto flotante son errores de redondeo, cancelaciones, empantanamiento y conversiones intermedias. Los resultados inesperados no son bugs de MATLAB y se producen en cualquier software que utilice números de punto flotante. Para representaciones racionales exactas de números, considere usar Symbolic Math Toolbox™.
Errores de redondeo
Los errores de redondeo se pueden producir debido a la representación con precisión finita de números de punto flotante. Por ejemplo, el número 4/3
no se puede representar de manera exacta como una fracción binaria. De esta forma, este cálculo devuelve la cantidad eps(1)
en lugar de 0
.
e = 1 - 3*(4/3 - 1)
e = 2.2204e-16
De forma similar, dado que pi
no es una representación exacta de π, sin(pi)
no es exactamente cero.
x = sin(pi)
x = 1.2246e-16
Los errores de redondeo se observan mejor cuando se realizan muchas operaciones en números flotantes, lo que permite a los errores acumularse y agravarse. Una práctica recomendada es minimizar el número de operaciones siempre que sea posible.
Cancelación
La cancelación puede producirse cuando se resta un número de otro número de aproximadamente la misma magnitud, medida por eps
. Por ejemplo, eps(2^53)
es 2
, de modo que los números 2^53 + 1
y 2^53
tienen la misma representación de punto flotante.
x = (2^53 + 1) - 2^53
x = 0
Cuando sea posible, intente reescribir los cálculos en un formato equivalente que evite las cancelaciones.
Empantanamiento
El empantanamiento puede producirse cuando se realizan operaciones en números de punto flotante con una diferencia entre ellos de muchos órdenes de magnitud. Por ejemplo, este cálculo muestra una pérdida de precisión que hace que la suma sea insignificante.
x = 1 + 1e-16
x = 1
Conversiones intermedias
Cuando realiza operaciones aritméticas con diferentes tipos de datos, los cálculos y las conversiones intermedias pueden generar resultados inesperados. Por ejemplo, aunque tanto x
como y
son 0.2
, restarlos genera un resultado distinto de cero. La razón es que y
se convierte en primer lugar a double
antes de realizar la resta. Después, el resultado de esta resta se convierte a single
, z
.
format long
x = 0.2
x = 0.200000000000000
y = single(0.2)
y = single 0.2000000
z = x - y
z = single -2.9802323e-09
Álgebra lineal
Los problemas habituales en las operaciones aritméticas, como los descritos anteriormente, pueden agravarse cuando se aplican a problemas de álgebra lineal porque los cálculos relacionados constan normalmente de varios pasos. Por ejemplo, cuando se resuelve el sistema de ecuaciones lineales Ax = b
, MATLAB advierte de que es posible que los resultados no sean precisos porque la matriz de operandos A
está mal condicionada.
A = diag([2 eps]); b = [2; eps]; x = A\b;
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.110223e-16.
Referencias
[1] Moler, Cleve. Numerical Computing with MATLAB. Natick, MA: The MathWorks, Inc., 2004.