Debido 1.1
y 3.3
son floating point numbers. Las fracciones decimales, como .1 o .3, no son exactamente representables en un número de punto flotante binario. .1 significa 1/10. Para representar eso en binario, donde cada dígito fraccionario representa 1/2 n (1/2, 1/4, 1/8, etc.), necesitaría un número infinito de dígitos, 0.000110011 ... repitiéndose infinitamente.
Este es exactamente el mismo problema que representar, por ejemplo, 1/3 en la base 10. En la base 10, necesitarías un número infinito de dígitos, .33333 ... para siempre, para representar 1/3 exactamente. Así que trabajando en la base 10, usualmente redondeas, a algo así como .33. Pero si suma tres copias de eso, obtiene .99, no 1.
Para obtener más información sobre el tema, lea What Every Computer Scientist Should Know About Floating Point Arithmetic.
Para representar números racionales con mayor precisión en Haskell, siempre puede usar el tipo de datos racional, Ratio
; junto con bignums (enteros arbitrariamente grandes, Integer
en Haskell, a diferencia de Int
que son de tamaño fijo) como el tipo de numerador y denominador, puede representar números racionales arbitrariamente precisos, pero a una velocidad significativamente más lenta que los números de coma flotante, que son implementado en hardware y optimizado para la velocidad.
Los números de coma flotante son una optimización, para cálculo científico y numérico, que intercambia precisión para alta velocidad, lo que le permite realizar una gran cantidad de cálculos en poco tiempo, siempre que sepa redondear y cómo afecta tus cálculos.
Agradable javascript float - decimal - visualizador binario: http://babbage.cs.qc.edu/IEEE-754/Decimal.html – Seth
Este no es un problema específico de Haskell: lo mismo sucederá en cualquier idioma que usa números de coma flotante. Los detalles precisos dependen de la implementación del punto flotante, pero la mayoría de los procesadores usan IEEE-754, que está estrechamente especificado para garantizar que los programas se comporten de la misma manera en todas partes. –