La documentación para la función round () indica que le pasa un número y las posiciones pasan del decimal a round. Por lo tanto, debería hacer esto:
n = 5.59
round(n, 1) # 5.6
Pero, en realidad, la vieja rareza de punto flotante se arrastra y obtienes:
5.5999999999999996
A los efectos de la interfaz de usuario, necesito mostrar 5.6
. Busqué en Internet y encontré algo de documentación que depende de mi implementación de Python. Desafortunadamente, esto ocurre tanto en mi máquina de desarrollo de Windows como en cada servidor Linux que he probado. Ver aquí también .
A falta de crear mi propia biblioteca redonda, ¿hay alguna forma de evitar esto?
python
floating-point
rounding
swilliams
fuente
fuente
round(5.55, 1) = 5.5
.Respuestas:
No puedo evitar la forma en que está almacenado, pero al menos el formateo funciona correctamente:
fuente
print '%.2f' % 655.665
pero vuelve655.66
, debería serlo655.67
from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_DOWN
# uso para redondear números flotantesDecimal(str(655.665)).quantize(Decimal('1.11'), rounding=ROUND_HALF_UP)
# Problemas y limitaciones en puntos flotantesEl formateo funciona correctamente incluso sin tener que redondear:
fuente
"{:.1f}".format(n)
'%.5f' % 0.988625
da0.98862
Si usa el módulo Decimal, puede aproximarse sin el uso de la función 'redonda'. Esto es lo que he estado usando para redondear, especialmente al escribir aplicaciones monetarias:
Esto devolverá un número decimal que es 16.20.
fuente
rounding='ROUND_UP'
NameError: global name 'ROUND_UP' is not defined
es necesario importar su función de redondeo:from decimal import Decimal, ROUND_UP
. Otras funciones de redondeoround(5.59, 1)
está funcionando bien El problema es que 5.6 no se puede representar exactamente en coma flotante binaria.Como dice Vinko, puede usar el formato de cadena para redondear para mostrar.
Python tiene un módulo para aritmética decimal si lo necesita.
fuente
Obtienes '5.6' si lo haces en
str(round(n, 1))
lugar de soloround(n, 1)
.fuente
Puede cambiar el tipo de datos a un entero:
Y luego muestre el número insertando el separador decimal de la localidad.
Sin embargo, la respuesta de Jimmy es mejor.
fuente
La matemática de punto flotante es vulnerable a imprecisiones de precisión leves pero molestas. Si puede trabajar con un número entero o fijo, se le garantizará la precisión.
fuente
Echa un vistazo al módulo Decimal
y
Decimal proporciona el tipo de operaciones que facilitan la escritura de aplicaciones que requieren operaciones de punto flotante y también necesitan presentar esos resultados en un formato legible para humanos, por ejemplo, contabilidad.
fuente
printf el tonto.
fuente
Es un gran problema de hecho. Prueba este código:
Muestra 4.85. Entonces haces:
y muestra 4.8. ¿Hacen cálculos a mano? La respuesta exacta es 4.85, pero si intentan:
puedes ver la verdad: el punto flotante se almacena como la suma finita más cercana de fracciones cuyos denominadores son potencias de dos.
fuente
Puede usar el operador de formato de cadena
%
, similar a sprintf.fuente
Funciona perfecto
fuente
Estoy haciendo:
En este caso, primero redondeamos adecuadamente a nivel de unidad, luego lo convertimos a entero para evitar imprimir un flotante.
entonces
Creo que esta respuesta funciona mejor que formatear la cadena, y también tiene más sentido para mí usar la función redonda.
fuente
Evitaría confiar
round()
en absoluto en este caso. Considerarsaldrá
que no es una salida deseada si necesita redondeo sólido al entero más cercano. Para evitar este comportamiento, vaya con
math.ceil()
(omath.floor()
si desea redondear hacia abajo):salidas
Espero que ayude.
fuente
Código:
Salida:
fuente
Aquí es donde veo que falla la ronda. ¿Qué pasaría si quisieras redondear estos 2 números a un decimal? 23.45 23.55 Mi educación fue que al redondear estos debería obtener: 23.4 23.6 la "regla" es que debe redondear si el número anterior era impar, no redondear si el número anterior era par. La función redonda en python simplemente trunca el 5.
fuente
El problema es solo cuando el último dígito es 5. Ej. 0.045 se almacena internamente como 0.044999999999999 ... Simplemente puede incrementar el último dígito a 6 y redondear. Esto te dará los resultados deseados.
fuente
Otra opción potencial es:
fuente
Qué pasa:
fuente
epsilon = .000001
entoncesround(1.0/5.0, 1) + epsilon
tomaría la representación precisa 0.2 y la haría 0.00001. Problemas igualmente malos ocurrirían si el épsilon estuviera dentro de la función redonda.