Ya hemos aprendido a almacenar números enteros tanto positivos como negativos. Ahora vamos a ver números fraccionarios.
Los números fraccionarios, o como normalmente los llamamos “números con decimales”, son aquellos que no corresponden con partes enteras (ejemplo, 0.5, 2.31, 7.353, son números fraccionarios).
Representar números fraccionarios es más complicado que representar números enteros positivos o negativos. Así que tenemos distintas formas de representación, siendo la más habitual la de coma flotante.
Representación de punto fijo
Una de las formas más simples de representar números con decimales en binario es el método de punto fijo. En este enfoque, se asigna un número fijo de bits para la parte entera y otro número fijo para la parte fraccionaria del número.
Por ejemplo, en un sistema de 8 bits con 4 bits para la parte entera y 4 para la parte decimal, el número 5.75
se representaría como 0101.1100
.
Esta técnica es directa y fácil de implementar, pero tiene muchas limitaciones. La precisión está limitada por el número de bits dedicados a la parte fraccionaria.
Además, no es dinámico y no puede manejar números que excedan el rango definido por los bits asignados
Representación en coma flotante
El método de coma flotante es el estándar de facto para representar números con decimales en la mayoría de las computadoras modernas. Este método permite una mayor flexibilidad y precisión al manejar números de diferentes magnitudes.
El estándar IEEE 754 es el más utilizado para la representación de números en coma flotante.
En la representación en coma flotante, un número se divide en tres partes: el signo, el exponente y la mantisa.
- El signo indica si el número es positivo o negativo.
- El exponente determina dónde está el punto decimal.
- La mantisa es la parte fraccionaria del número.
Por ejemplo, el número 5.75
en formato de 32 bits en coma flotante sería:
0 10000001 01110000000000000000000
- Signo:
0
(positivo) - Exponente:
10000001
(129 en decimal) - Mantisa:
01110000000000000000000
Este método permite manejar números de magnitudes muy diferentes al ajustar el exponente. Per también tiene sus limitaciones, especialmente en términos de precisión para números muy pequeños o muy grandes.
La representación es más compleja que la representación en coma fijo, y requiere mayor coste computacional. Pero, a cambio, nos deja abarcar una enorme cantidad de números.
Problemas de precisión
A pesar de su versatilidad, la representación de números decimales en punto flotante puede llevar a problemas de precisión. Esto es debido a que en realidad, no estamos codificando un número si no “un número muy cercano”.
Por ejemplo, el número decimal 0.1 no puede ser representado con precisión en sistema binario y resulta en una representación periódica en binario.
En coma flotante ese número es
- Signo:
0
- Exponente: 123 en decimal
- Mantisa: 5033165
Es decir, que el número que realmente estás representando no es 0.1, si no
0.100000001490116119384765625
Es una diferencia pequeña, pero genera muchísimos problemas y aparentes contradicciones al programar.
Ejemplos reales de “cosas raras” que te pueden pasar
Que sumar diez veces 0.1 y restarle 1.0, no sea cero.
0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 - 1.0 = −2.77556×10^−17
O que al restar estos dos números, no obtengas 0.00001, que sería lo “normal”.
1.00001 - 1.0 = 0.00000999999
O incluso, que el resultado sea diferente en función del orden en el que hagas las operaciones
(0.1 + 0.2) + 0.3 = 0.6000000000000001
0.1 + (0.2 + 0.3) = 0.6
Es decir, hay que tratar los números con coma flotante con precaución. No es que sean malo, es que hay que entender cómo funcionan para saber trabajar con ellos.
Otras representaciones
Existen otras técnicas mucho menos comunes, pero igualmente interesantes para representar números con decimales en binario. Algunas de estas incluyen:
Notación de punto medio: En esta técnica, se representa un número como la suma de dos números en punto fijo. Esto puede ser útil en situaciones donde se requiere una alta precisión y el rango no es una preocupación principal.
Método de coma fija: Similar al punto fijo, pero con un número variable de bits para la parte fraccionaria. Esto puede permitir una mayor precisión para ciertos números, pero a costa de flexibilidad en el rango.
Punto flotante normalizado: Una variante del coma flotante que garantiza que el bit más significativo de la mantisa siempre sea
1
, lo que mejora la precisión y el rango en comparación con el coma flotante estándar.