¿Por qué la ronda (2.4999999999999999992) devuelve 3

Estoy trabajando en el progtwig de matemáticas y tengo un problema bastante grande con la ronda. Así que después de que mi progtwig hizo algunos cálculos, redondea el resultado.

Todo funciona bien, pero si el result == 2.49999999999999992 , la función de vuelta devuelve 3.0 lugar de 2.0 .

¿Cómo puedo arreglar eso?

Gracias.

Como @Pavel Anossov dice en su comentario, there's no such thing as 2.49999999999999992 in IEEE 754, 2.49999999999999992 == 2.5. . La flotación puede ser siempre crítica para sus cálculos, porque en cualquier caso (flotación de 32/64/128 bits), tiene un límite de precisión. Obviamente, esto también se limita a los flotadores de Python.

Hay diferentes opciones para lidiar con eso, por ejemplo, podría usar la biblioteca decimal :

 >>> from decimal import * >>> getcontext().prec = 6 >>> Decimal(1) / Decimal(7) Decimal('0.142857') >>> getcontext().prec = 28 >>> Decimal(1) / Decimal(7) Decimal('0.1428571428571428571428571429') 

Es posible establecer la precisión usted mismo en ese caso. decimal está en la biblioteca estándar.

También hay bibliotecas de terceros como bigfloat , que podrías usar (no tengo experiencia con eso):

 >>> from bigfloat import * >>> sqrt(2, precision(100)) # compute sqrt(2) with 100 bits of precision 

Pero como puedes ver, siempre tienes que elegir una precisión. Si realmente no quieres perder ningún tipo de precisión, usa fracciones (también en la biblioteca estándar):

 >>> from fractions import Fraction >>> a = Fraction(16, -10) >>> a Fraction(-8, 5) >>> a / 23 Fraction(-8, 115) >>> float(a/23) -0.06956521739130435 

La razón es que el tipo de coma flotante de Python (generalmente los números de punto flotante de precisión doble IEEE 754) no tiene un valor de 2.49999999999999992. Los números de punto flotante generalmente están en la forma mantissa*base**exponent , y en Python puede encontrar los límites para float en particular dentro de sys.float_info . Para empezar, calculemos cuántos dígitos puede contener la propia mantisa:

 >>> from sys import float_info >>> print float_info.radix**float_info.mant_dig # How big can the mantissa get? 9007199254740992 >>> print "2.49999999999999992" 2.49999999999999992 >>> 2.49999999999999992 2.5 

Claramente el número que hemos ingresado es más amplio. ¿Qué tan cerca podemos ir antes de que las cosas salgan mal?

 >>> print 2.5*float_info.epsilon 5.55111512313e-16 

e-16 aquí significa *10**-16 , así que reformatéelo para comparar:

 >>> print "%.17f"%(2.5*float_info.epsilon); print "2.49999999999999992" 0.00000000000000056 2.49999999999999992 

Esto indica que a una magnitud de alrededor de 2.5, las diferencias inferiores a alrededor de 5.6e-16 (incluido este 8e-17) se perderán en el almacenamiento en sí. Por lo tanto este valor es 2.5, que se redondea.

También podemos calcular una estimación de cuántos dígitos significativos podemos usar:

 >>> import math, sys >>> print math.log10(sys.float_info.radix**sys.float_info.mant_dig) 15.9545897702 

Muy cerca, pero no del todo, 16. En binario, el primer dígito siempre será 1, por lo que podemos tener un número conocido de dígitos significativos (mant_dig), pero en decimal el primer dígito consumirá entre uno y cuatro bits. Esto significa que el último dígito puede estar desactivado por más de uno. Por lo general, ocultamos esto imprimiendo solo con una precisión limitada, pero en realidad ocurre con muchos números:

 >>> print '%f = %.17f'%(1.1, 1.1) 1.100000 = 1.10000000000000009 >>> print '%f = %.17f'%(10.1, 10.1) 10.100000 = 10.09999999999999964 

Tal es la imprecisión inherente de los números de punto flotante. Los tipos como bigfloat , decimal y fractions (gracias a David Halter por estos ejemplos) pueden empujar los límites, pero si empiezas a mirar muchos dígitos debes estar al tanto de ellos. También tenga en cuenta que esto no es exclusivo de las computadoras; un número irracional, como pi o sqrt (2), no se puede escribir exactamente en ninguna base de enteros.