Archivo del sitio

Ya no se redondea como en los viejos tiempos

Hoy he asistido sorprendido a uno de esos momentos que hace que te explote la cabeza. Todo empezó con este tuit:

tuit1

Rápidamente me puse manos a la obra y lo probé en python, con la ventaja de que por las particularidades de este lenguaje siempre tengo instaladas dos versiones en los ordenadores que uso.

Capturapython

Así que en la versión 2.7 de Python vemos el redondeo “de toda la vida”, en el que el redondeo de 1.5 es 2 y el redondeo de 2.5 es 3. Pero si ejecutamos el mismo código para la versión 3.2 de Python tenemos que para ambos casos el resultado es 2.

¿El mundo se ha vuelto loco? Eso es lo primero que pensé, pero resulta que no, todo esto tiene su lógica. En pocos tuits se resolvió el misterio:

tuit2

tuit3

Y de paso se demostró que soy un empanado que no se había enterado de este cambio. El IEEE 754 es un estándar para el tratamiento de números en coma flotante, o hablando para no informáticos: para tratar números con decimales. Y en este estándar se recomienda, desde 2008, que el redondeo que se debe usar es Round half to even. 

Con este redondeo lo que se hace es el redondeo de toda la vida con una excepción para los números que tienen como decimal 0.5. Cuando la parte decimal es 0.5 lo que se hace es redondear al entero par más cercano al número. Por eso al redondear 2.5 lo que obtenemos es un 2 en lugar de un 3, ya que 2 es el número entero par más cercano a 2.5.

¿Por qué? Maldita sea ¡Por qué!

Después de mi sorpresa e ira inicial y de buscar un poco de información me di cuenta de que el asunto tenía mucha lógica. ¿Por qué un número que acaba en 0.5 debe ser redondeado al entero inmediatamente superior? Al fin y al cabo está a medio camino entre dos enteros, elegir el entero superior es simplemente un acuerdo al que hemos llegado los falibles humanos. Lo justo en este caso, sería que en la mitad de los casos el redondeo sea hacia arriba y en la otra mitad, el redondeo fuera hacia abajo. Y precisamente eso es lo que consigue este método.

Además el redondeo clásico provocaba un problema al tratar con números negativos:

Capturapythonnegativos

En el redondeo clásico de números con 0.5 como parte decimal en nuestros programas estábamos eligiendo el entero inmediatamente superior para números positivos y el inmediatamente inferior para números negativos (3 es mayor que 2.5 y -3 es menor que -2.5). Si lo pensamos fríamente, no parece demasiado correcto. Con el nuevo método los números negativos y positivos pueden ser redondeados a su entero inmediatamente superior o inferior.

[Añadido] Como bien apunta darth_suicune en los comentarios, el motivo de escoger este método es más profundo y afecta directamente al hecho de realizar cálculos una vez realizado el redondeo. En banca se lleva usando muchos años este redondeo y también se le denomina redondeo Gaussiano o estadístico. Pues bien, con este redondeo los cálculos posteriores al redondeo (y sobre todo medias) son más precisos que cuando se usa un redondeo estándar.

Así que ya sabéis, hemos redondeado por encima de nuestras posibilidades y ha llegado la troika de los estándares y nos ha dado un buen meneo. Lo único que este meneo nos lo dieron hace años y yo no me he enterado hasta ahora, empanado que es uno.

Así me siento hoy. (Fuente Wikipedia)

Así me siento hoy. (Fuente Wikipedia)

PD: Podéis comprobar en Wolfram Alpha que la cosa va en serio:

round25wa

Anuncios
A %d blogueros les gusta esto: