La representación de coma flotante (en inglés, floating point) es una forma de notación científica usada en las computadoras con la cual se pueden representar números reales extremadamente grandes y pequeños de una manera muy eficiente y compacta y con la que se pueden realizar operaciones aritméticas. Como la representación en coma flotante es casi idéntica a la notación científica tradicional, con algunos añadidos y algunas diferencias, primero se describirá la notación científica para entender cómo funciona y luego se describirá la representación de coma flotante y las diferencias.
Es importante señalar que, aunque esta guía profundiza en el concepto, las propiedades y el manejo de los números de punto flotante en diversos entornos de programación, el material proporcionado no incluye detalles específicos ni ejemplos sobre cómo declarar una variable de tipo flotante en LPP (Lenguaje de Programación Pascal). No obstante, los principios y consideraciones aquí expuestos son universalmente aplicables a la comprensión de este tipo de datos.
¿Qué son los Números de Punto Flotante?
Los números de punto flotante se refieren 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. Los números de punto flotante utilizan el formato IEEE (Institute of Electrical and Electronics Engineers).
Notación Científica como Base
La notación científica se usa para representar números reales. El coeficiente tiene una cantidad determinada de dígitos significativos, los cuales indican la precisión del número representado; cuantos más dígitos tenga el coeficiente, más precisa es la representación. El coeficiente se multiplica por la base elevada a un exponente entero. En el sistema decimal la base es 10. Al multiplicar el coeficiente por la base elevada a una potencia entera, se desplaza la coma del coeficiente tantas posiciones (tantos dígitos) como indique el exponente. El valor de la potencia indica cuántas posiciones (cuántos dígitos) debe desplazarse la coma del coeficiente para obtener el número real final. El signo de la potencia indica si ese desplazamiento de la coma debe hacerse hacia la derecha o hacia la izquierda: una potencia positiva indica que el desplazamiento de la coma es hacia la derecha, mientras que un signo negativo indica que el desplazamiento debe ser hacia la izquierda. Si el exponente es cero, la coma no se desplaza ninguna posición. Para la entrada y el despliegue de números en notación científica, las computadoras y las calculadoras pueden representarlos de diferentes maneras, como por ejemplo 2,99792458d8, usada en el lenguaje BASIC para representar números de doble precisión, o 2,99792458 x 108, usada en calculadoras.
Precisión Limitada de los Números de Punto Flotante
La coma flotante permite representar solo una cantidad limitada de dígitos de un número real; es decir, solo se trabajará con los dígitos más significativos (los de mayor peso) del número real, de tal manera que un número real generalmente no se podrá representar con total precisión sino como una aproximación que dependerá de la cantidad de dígitos significativos que tenga la representación en coma flotante con que se está trabajando. La limitación se halla cuando existen dígitos de peso menor al de los dígitos de la parte significativa. En este caso, estos suelen redondearse y, si son muy pequeños, se truncan.
Lea también: IVA 21% Excel
Los números de punto flotante tienen una precisión limitada. 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.
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) y 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.
Representación Interna y Problemas de Precisión
PHP utiliza el formato de precisión decimal IEEE 754, que dará un error relativo máximo del orden de 1.11e-16 (debido a los redondeos). Esto se debe a la representación exacta como números de punto flotante en base 2, utilizada internamente, y esto independientemente del tamaño de la mantisa. Números como 0.1 y 0.7 son non-terminating en binario, por lo que también son truncados, y la suma de estos números truncados no se suma a la representación binaria truncada de 0.8. La igualdad de valores de números de punto flotante es problemática, debido a la forma en que se representan internamente. Para probar la igualdad de valores de números de punto flotante, se utiliza un límite superior del error relativo al redondeo.
En la representación binaria de coma flotante, el bit de mayor peso define el valor del signo (0 para positivo y 1 para negativo). Le siguen una serie de bits que definen el exponente. Debido a que la parte significativa está generalmente normalizada, en estos casos el bit más significativo de la parte significativa siempre es 1, así que no se representa cuando se almacena sino que se asume implícitamente. Para poder realizar los cálculos, ese bit implícito se hace explícito antes de operar con el número en coma flotante. Hay otros casos donde el bit más significativo no es un 1, como en la representación del número cero, o cuando el número es muy pequeño en magnitud y rebasa la capacidad del exponente, en cuyo caso los dígitos significativos se representan de una manera denormalizada para no perder la precisión de un solo golpe sino progresivamente.
Un valor indefinido o no representable en cálculos con números de punto flotante es representado por la constante NAN.
Lea también: Guía IVA reducido
Tipos de Datos Flotantes: float y double
Puede declarar variables como float o double, según las necesidades de la aplicación. Las diferencias principales entre los dos tipos son la precisión que pueden representar, el almacenamiento que requieren y su intervalo. 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.
float (Precisión Sencilla)
Los valores de precisión sencilla con el tipo float tienen 4 bytes, formados por un bit de signo, un exponente binario de 8 bits con exceso 127 y una mantisa de 23 bits. La mantisa representa un número entre 1,0 y 2,0. Puesto que el bit de alto nivel de la mantisa siempre es 1, no se almacena en el número. Para el tipo float, la diferencia del exponente es 127.
El almacenamiento de un número single (precisión simple) 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 |
double (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 el tipo double, la diferencia del exponente es 1023.
El almacenamiento de un número double (doble precisión) requiere 64 bits, tal como se muestra en esta tabla:
Lea también: ¿Cómo localizar tus XML del SAT?
| 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 |
Comparativa de Tipos de Punto Flotante
El bit más significativo de cualquier tipo float o double es siempre el bit de signo. La mantisa se almacena como una fracción binaria mayor o igual que 1 y menor que 2. Si la precisión no es tan importante como el almacenamiento, considere la posibilidad de usar el tipo float para las variables de punto flotante. Las variables de punto flotante se pueden promover a un tipo más significativo (de tipo float a tipo double). La promoción se produce cuando se realizan operaciones aritméticas en variables de punto flotante. Estas operaciones aritméticas siempre se realizan con un grado tan alto de precisión como la variable con el máximo grado de precisión.
En la siguiente tabla se muestra el número de bits asignados a la mantisa y el exponente de cada tipo de punto flotante, así como sus tamaños y el sesgo del exponente:
| Tipo | Signo | Exponente | Significante | Total Tamaño | Bias del exponente | Bits de precisión |
|---|---|---|---|---|---|---|
| Medio (half) | 1 | 5 | 10 | 2 bytes (16 bits) | 15 | 11 |
| Simple (single) | 1 | 8 | 23 | 4 bytes (32 bits) | 127 | 24 |
| Doble (double) | 1 | 11 | 52 | 8 bytes (64 bits) | 1023 | 53 |
Manejo de Números de Punto Flotante en Entornos de Programación
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. 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.
Creación de Datos de Doble Precisión en MATLAB
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. Puede convertir datos numéricos, caracteres o cadenas, y datos lógicos a doble precisión usando la función double.
Creación de Datos de Precisión Simple en MATLAB
Para crear un número de precisión simple, utilice la función single. También puede convertir datos numéricos, caracteres o cadenas, y datos lógicos a precisión simple usando la función single.
Valores Extremos y Vacíos entre Números
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.
Puede determinar el tamaño de un vacío entre números de punto flotante consecutivos usando la función eps. 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. 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.
La función flintmax devuelve el entero consecutivo más grande en formato de punto flotante. 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.
Operaciones Aritméticas con Números 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. 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.
Resultados Inesperados y Errores Comunes
Los resultados inesperados no son bugs de MATLAB y se producen en cualquier software que utilice números de punto flotante. 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.
- Errores de Redondeo: 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. 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. De forma similar, dado que pi no es una representación exacta de π, sin(pi) no es exactamente cero.
- 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. 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, un cálculo puede mostrar una pérdida de precisión que hace que la suma sea insignificante.
- 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.
Consideraciones en Otros Lenguajes (PHP)
En PHP, la igualdad de valores de números de punto flotante es problemática. PHP piensa que 1.6 (proveniente de una diferencia) no es igual a 1.6. Esto sucede probablemente porque $x no es realmente 1.6, sino 1.599999... Esto falla en algunos casos debido a la precisión oculta (un problema estándar de C, del que la documentación de PHP no hace mención). var_dump puede decir que las variables son idénticas, y deberían ser idénticas (comenzaron en 0.01 y se añadió 0.001 repetidamente), pero no lo son. Hay algo de precisión oculta.
Los números de punto flotante pueden ser convertidos sin una pequeña pérdida de precisión. echo gettype(19.6*100) devuelve 'double'. Sea cuidadoso al usar valores float en cadenas que se usan como código más tarde, por ejemplo, al generar código JavaScript o sentencias SQL. El float se formatea de acuerdo a la configuración regional del navegador, lo que significa que "0.23" resultará en "0,23". Esto daría un resultado diferente para usuarios con algunas configuraciones regionales.
Un consejo general de computación: si estás llevando un registro de dinero, hazte a ti mismo y a tus usuarios el favor de manejar todo internamente en centavos y hacer la mayor cantidad de matemáticas posible con enteros. Almacena los valores en centavos si es posible. Suma y resta en centavos.
Para convertir de float a binario y viceversa, no uses tus propias "funciones". El rendimiento de bucle en PHP es horrible. Usando pack/unpack utilizas la codificación del procesador, que siempre es correcta.
