10Pines / pdepreludat

BSD 3-Clause "New" or "Revised" License
24 stars 2 forks source link

Round numbers to avoid floating point problems #18

Closed JuanFdS closed 4 years ago

JuanFdS commented 4 years ago

Hay algunas operaciones como 0.1 + 0.7 que devuelven resultados raros como 0.7999999999999999

Esto no se lleva bien con que haya funciones que solo tienen sentido para enteros (como even o take), así que esto está causando algunos problemas.

La idea de este PR es redondear los numeros a 9 digitos para reducir ese comportamiento "inespereado" que surge por usar numeros de punto flotante.

La forma de encararlo no es directamente redondeando los numeros a medida que son resultados de operaciones, si no redondear los numeros cuando van a ser comparados. Entonces, se está redondeando solo en las funciones de las typeclasses Ord, Eq y Show. Eq para que expresiones como 0.1 + 0.7 == 0.8 sean verdad (aunque también va a seguir siendo verdad que 0.1 + 0.7 == 0.7999999999999999. Ord para mantener consistencia, porque con solo Eq pasa que 0.1 + 0.7 == 0.8 es True, pero tambien sería True 0.1 + 0.7 < 0.8. Show es para mostrar al usuario el valor redondeado porque ver 0.7999999999999999 podría desconcertar al alumno (?

Esto seguro que tiene errores. Por ejemplo, como en realidad no estamos perdiendo nada de informacion del Double que está siendo wrappeado, supongo que podrían stackearse suficientes digitos a los que no les damos bola en sucesivas operaciones sin que nos demos cuenta y en algún momento lleguen a cambiar el valor redondeado.

Si se les ocurren cosas que podrían salir terriblemente mal por mergear esto avisen :P