Errores en punto flotante

Hace poco salió la noticia de que el Microsoft Excel suspendía las matemáticas, y poco despues me encontré con que los navegadores basados en Gecko también, y sin embargo el Internet Explorer las aprobaba.

Viendo los comentarios de la gente, me entraron ganas de aclarar un poco este último tema, y a eso es a lo que dedico este post.

Como supongo que sabreis, hay varias tipos de representaciones informáticas para los números (enteros con y sin signo, y reales, generalmente en punto flotante, punto fijo… entre otros)

¿Cuál es el problema? Que un número real puede tener infinitas cifras, generalmente decimales, y la memoria de un PC es limitada.

Esto es, si nos basamos en la representación en punto flotante que se usan 32 bits para guardar un número real en precisión simple, de los cuales:

  • 1 bit es para el signo (0 positivo y 1 negativo).
  • 8 bits para el exponente (almacenado en exceso a 127, es decir, sin signo y el 127 representa el cero, el 126 el menos uno…)
  • 23 bits para la mantisa

También hay que tener en cuenta la normalización de los números. Es decir, un número siempre se almacenará de la forma ±0.M x BE, siendo M la mantisa, E el exponente y B la base, que en el caso de un ordenador es 2.

Como se puede imaginar, no se pueden representar todos los números reales, por lo que se pueden adoptar distintas medidas:

  • Representación truncada: Un número se representa mediante la suma de varios, para obtener más precisión, de la forma: ±0.d1d2…dt * BE + ±0.dtdt+1... * BE-t siendo t el número de cifras de la mantisa, en nuestro caso, 23 bits.
  • Representación redondeada: Es el caso más común, y consiste en redondear el número que queremos representar al número representable más cercano (p.e. si solo pudiésemos representar enteros, el 9.3 ~> 9, y el 23.8 ~> 24).
    Esta es la representación que los ordenadores suelen usar, y si necesitan más precisión, pues se aumenta el tamaño del número. (Doble precisión = 64 bits…)

Se llama epsilon de una máquina (ε) al valor que representa la exactitud de la misma. Es decir, el menor valor que cumpla:
1.0+ε > 1.0
Vamos, que la máquina no nos redondee ese número a 1.0, y que por tanto sea representable.

Este valor vale 1/2*B1-t (siendo B la Base y t los bits de la mantisa). Para 32 bits y en base 2, esto vale 1/2*21-23.

Una vez introducidos en los datos técnicos, podemos acotar el error de la representación de los números flotantes en precisión simple a:

|Error| < ε, lo que nos deja que:

|Error| < 2-23.

Por eso es tan frecuente ver, en todas las operaciones con números flotantes, que matemáticamente tendrían que ser exactas, como 5.2-0.1, que dan errores de redondeo como 5.09999999 y demás.

Es algo normal y no significa que el ordenador no sepa restar, sumar y demás, sino que no puede representarlo.

¿Y entonces, por qué el Internet Explorer si lo muestra bien?

La misma pregunta lo responde. Lo muestra bien, pero internamente tiene el mismo valor. Lo que hace es redondearlo antes de sacarlo por pantalla, es decir, si internamente tiene el valor de 4.999999999999 pues muestra 5.

Por eso en la página anterior dicen que aprueba las matemáticas, pero con trampas 😉

Para terminar, un ejemplo que prueba esto último.

  1. Introduce en la barra de dirección: javascript:(5.2-0.1).toFixed(24), esto muestra la resta de 5.2 – 0.1 con 24 decimales. Como puedes ver, hay un error cometido a partir del decimal número 16 (esto puede variar dependiendo del ordenador que se use).
  2. Introduce en la barra de dirección: javascript:(5.2-0.1).toFixed(10), ahora mostramos la misma operación, pero con solo 10 decimales. Ah! Ahora es exacta! No, simplemente está truncada 😉
Anuncios

One Response to Errores en punto flotante

  1. JavaMan dice:

    Un Comentario nada + pongas ejemplos para que nos guiemos de ellos

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: