número flotante de python

Estoy un poco confundido por qué Python agrega un número decimal adicional en este caso, por favor, ayuda a explicar

>>> mylist = ["list item 1", 2, 3.14] >>> print mylist ['list item 1', 2, 3.1400000000000001] 

Los números de punto flotante son una aproximación, no pueden almacenar exactamente números decimales. Debido a que intentan representar un rango muy grande de números en solo 64 bits, deben aproximarse en cierta medida.

Es muy importante tener esto en cuenta, ya que produce algunos efectos secundarios extraños. Por ejemplo, podría pensar razonablemente que la sum de diez lotes de 0.1 sería 1.0 . Si bien esto parece lógico, también es incorrecto cuando se trata de punto flotante:

 >>> f = 0.0 >>> for _ in range (10): ... f += 0.1 ... >>> print f == 1.0 False >>> f 0.99999999999999989 >>> str(f) 1.0 

Se podría pensar que n / m * m == n . Una vez más, el mundo de punto flotante no está de acuerdo:

 >>> (1.0 / 103.0) * 103.0 0.99999999999999989 

O tal vez, tan extrañamente, uno podría pensar que para todos n , n + 1 != n En tierra de punto flotante, los números simplemente no funcionan así:

 >>> 10.0**200 9.9999999999999997e+199 >>> 10.0**200 == 10.0**200 + 1 True # How much do we have to add to 10.0**200 before its # floating point representation changes? >>> 10.0**200 == 10.0**200 + 10.0**183 True >>> 10.0**200 == 10.0**200 + 10.0**184 False 

Vea lo que todo científico informático debe saber sobre los números de punto flotante para obtener un excelente resumen de los problemas.

Si necesita una representación decimal exacta, consulte el módulo decimal , parte de la biblioteca estándar de Python desde 2.4. Te permite especificar el número de cifras significativas. La desventaja es que es mucho más lento que el punto flotante, porque las operaciones de punto flotante se implementan en hardware mientras que las operaciones decimales ocurren puramente en software. También tiene sus propios problemas de imprecisión, pero si necesita una representación exacta de números decimales (por ejemplo, para una aplicación financiera) es ideal.

Por ejemplo:

 >>> 3.14 3.1400000000000001 >>> import decimal >>> decimal.Decimal('3.14') >>> print decimal.Decimal('3.14') 3.14 # change the precision: >>> decimal.getcontext().prec = 6 >>> decimal.Decimal(1) / decimal.Decimal(7) Decimal('0.142857') >>> decimal.getcontext().prec = 28 >>> decimal.Decimal(1) / decimal.Decimal(7) Decimal('0.1428571428571428571428571429') 

Vale la pena tener en cuenta que Python 3.1 tiene una nueva rutina de salida de punto flotante que redondea esto de la manera esperada (también ha sido portada a Python 2.7):

 Python 3.1 (r31:73572, Aug 15 2009, 17:12:41) [GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> a = [3.14] >>> print(a) [3.14] 

Del documento Novedades en Python 3.1 :

Python ahora usa el algoritmo de David Gay para encontrar la representación de punto flotante más corta que no cambia su valor. Esto debería ayudar a mitigar parte de la confusión que rodea a los números binarios de punto flotante.

El significado se ve fácilmente con un número como 1.1 que no tiene un equivalente exacto en punto flotante binario. Como no hay un equivalente exacto, una expresión como float('1.1') evalúa al valor representable más cercano que es 0x1.199999999999ap+0 en hexadecimal o 1.100000000000000088817841970012523233890533447265625 en decimal. El valor más cercano fue y aún se usa en los cálculos de punto flotante subsiguientes.

Como se mencionó anteriormente, se trata de puntos flotantes que son una aproximación.

Si desea exactitud, puede usar un decimal (que es una representación precisa): http://docs.python.org/library/decimal.html

 a = [1.5, 1.49999] a [1.5, 1.4999899999999999] from decimal import Decimal b = [1.5, Decimal('1.4999')] b [1.5, Decimal('1.4999')] 

Podemos arreglarlo con este comando:

 >>> x = 1.2 - 1.0 >>> x 0.19999999999999996 >>> y = float(str(x)) >>> y 0.2 

Añado una respuesta de @mark.