Quiero a
ser redondeado a 13.95 .
>>> a
13.949999999999999
>>> round(a, 2)
13.949999999999999
La round
función no funciona como esperaba.
python
floating-point
rounding
precision
ShadowRanger
fuente
fuente
Respuestas:
Se encuentra con el viejo problema con los números de coma flotante que no todos los números pueden representarse exactamente. La línea de comando solo le muestra el formulario de coma flotante completo de la memoria.
Con la representación de coma flotante, su versión redondeada es el mismo número. Dado que las computadoras son binarias, almacenan números de coma flotante como un número entero y luego lo dividen por una potencia de dos para que 13.95 se represente de manera similar a 125650429603636838 / (2 ** 53).
Los números de doble precisión tienen 53 bits (16 dígitos) de precisión y los flotantes regulares tienen 24 bits (8 dígitos) de precisión. El tipo de coma flotante en Python usa doble precisión para almacenar los valores.
Por ejemplo,
Si solo busca dos decimales (para mostrar un valor de moneda, por ejemplo), entonces tiene un par de opciones mejores:
fuente
"%.2f" % round(a,2)
puede incluir no solo en printf, sino también en cosas comostr()
float
) es solo la aproximación más cercana disponible del número decimal (con el que está familiarizado como ser humano). No existe tal valor binario (finitamente representable) como 0.245. Simplemente no existe, y matemáticamente no puede existir. El valor binario más cercano a 0.245 es ligeramente menor que 0.245, por lo que naturalmente se redondea hacia abajo. Del mismo modo, no existe el valor 0.225 en binario, pero el valor binario más cercano a 0.225 es ligeramente mayor que 0.225, por lo que naturalmente se redondea.Decimal
, usar , y esa fue una de las soluciones presentadas en esta respuesta. El otro era convertir sus cantidades a enteros y usar aritmética de enteros. Ambos enfoques también aparecieron en otras respuestas y comentarios.Hay nuevas especificaciones de formato, Mini-Idioma de especificación de formato de cadena :
Puedes hacer lo mismo que:
Nota 1: lo anterior devuelve una cadena. Para obtener el flotador, simplemente envuelva con
float(...)
:Nota 2: envolver con
float()
no cambia nada:fuente
'{0:,.2f}'.format(1333.949999999)
que imprime'1,333.95'
.float()
;float("{0:.2f}".format(13.9499999))
f"Result is {result:.2f}"
El incorporado
round()
funciona bien en Python 2.7 o posterior.Ejemplo:
Echa un vistazo a la documentación .
fuente
round(2.16, 1)
dará2.2
por qué pitón sólo ofrece unatruncate
func>>> round(2.675, 2) 2.67
docs.python.org/2/tutorial/floatingpoint.htmlNote The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float.
Siento que el enfoque más simple es usar la
format()
función.Por ejemplo:
Esto produce un número flotante como una cadena redondeada a dos puntos decimales.
fuente
Utilizar
en vez de
Debido a que esto último puede generar errores de salida al intentar generar múltiples variables (ver comentarios).
fuente
La mayoría de los números no pueden representarse exactamente en carrozas. Si desea redondear el número porque eso es lo que requiere su fórmula matemática o algoritmo, entonces desea usar redondear. Si solo desea restringir la visualización a una cierta precisión, ni siquiera use redondear y simplemente formatee como esa cadena. (Si desea mostrarlo con algún método de redondeo alternativo, y hay toneladas, entonces necesita mezclar los dos enfoques).
Y por último, aunque quizás lo más importante, si quieres matemáticas exactas , entonces no quieres flotadores en absoluto. El ejemplo habitual es tratar con dinero y almacenar 'centavos' como un número entero.
fuente
Prueba el siguiente código:
fuente
round
función en primer lugar. Por otro lado, debido a que esta solución todavía usa coma flotante, el problema original del OP permanece, incluso para la versión "corregida" de esta "solución".round
función (que se utilizó en la pregunta).round()
no funciona como el OP mencionado.TLDR;)
El problema de redondeo de entrada / salida ha sido resuelto definitivamente por Python 2.7.0 y 3.1 .
Un número correctamente redondeado puede convertirse reversiblemente de un lado a otro:
str -> float() -> repr() -> float() ...
oDecimal -> float -> str -> Decimal
Un tipo decimal ya no es necesario para el almacenamiento.
(Naturalmente, puede ser necesario redondear un resultado de la suma o resta de números redondeados para eliminar los errores acumulados del último bit. Una aritmética decimal explícita puede ser útil, pero una conversión a cadena por
str()
(es decir, redondeando a 12 dígitos válidos) ) es lo suficientemente bueno generalmente si no se requiere una precisión extrema o no se requiere un número extremo de operaciones aritméticas sucesivas).Prueba infinita :
Documentación
Consulte las notas de la versión Python 2.7 - Otros cambios de idioma en el cuarto párrafo:
El problema relacionado
Más información: El formato
float
anterior a Python 2.7 era similar al actualnumpy.float64
. Ambos tipos usan la misma precisión doble IEEE 754 de 64 bits con mantisa de 52 bits. Una gran diferencia es quenp.float64.__repr__
se formatea con frecuencia con un número decimal excesivo para que no se pueda perder ningún bit, pero no existe un número IEEE 754 válido entre 13.949999999999999 y 13.950000000000001. El resultado no es bueno y la conversiónrepr(float(number_as_string))
no es reversible con numpy. Por otra parte:float.__repr__
está formateado para que cada dígito sea importante; la secuencia no tiene espacios y la conversión es reversible. Simplemente: si tal vez tiene un número numpy.float64, conviértalo a flotante normal para formatearlo para humanos, no para procesadores numéricos, de lo contrario, no se necesita nada más con Python 2.7+.fuente
float
(doble precisión) y normalround
, no sobre numpy.double y su conversión a cadena. El redondeo simple de Python realmente no se puede hacer mejor que en Python 2.7. La mayoría de las respuestas se han escrito antes de 2.7, pero están obsoletas, aunque originalmente eran muy buenas. Esta es la razón de mi respuesta.1
, excepto durante el "desbordamiento gradual".a*b
vsb*a
. Gracias por los enlaces - Nostalgia.Con Python <3 (por ejemplo, 2.6 o 2.7), hay dos formas de hacerlo.
Pero tenga en cuenta que para las versiones de Python anteriores a 3 (por ejemplo, 3.2 o 3.3), se prefiere la opción dos .
Para obtener más información sobre la opción dos, sugiero este enlace sobre el formato de cadenas de la documentación de Python .
Y para obtener más información sobre la opción uno, este enlace será suficiente y tiene información sobre los distintos indicadores .
Referencia: Convierta el número de coma flotante con cierta precisión y luego cópielo en una cadena
fuente
numvar=12.456
, entonces"{:.2f}".format(numvar)
cede12.46
pero"{:2i}".format(numvar)
da un error y estoy esperando12
.Puede modificar el formato de salida:
fuente
Nadie parece haberlo mencionado todavía, así que permítanme dar un ejemplo en el formato f-string / template-string de Python 3.6, que creo que está muy bien:
Funciona bien con ejemplos más largos también, con operadores y que no necesitan parens:
fuente
Puede usar el operador de formato para redondear el valor hasta 2 decimales en python:
fuente
En Python 2.7:
fuente
output
tiene exactamente el mismo valor quea
, por lo que bien podría haber escrito enprint a
lugar deprint output
en la última línea.13.95
. Pero también lo haceprint a
, para este valor particular dea
, en Python 2.7, por lo que no está realmente claro cuál era el punto del paso de formateo.a == output
el código que muestras? DaTrue
por mí, y sospecho que también por ti.El tutorial de Python tiene un apéndice llamado Aritmética de coma flotante: problemas y limitaciones . Léelo Explica qué está sucediendo y por qué Python está haciendo todo lo posible. Incluso tiene un ejemplo que coincide con el tuyo. Déjame citar un poco:
Una alternativa y solución a sus problemas sería usar el
decimal
módulo.fuente
Como señaló @Matt, Python 3.6 proporciona cadenas f , y también pueden usar parámetros anidados :
que mostrará
result: 2.35
fuente
Está haciendo exactamente lo que le dijo que hiciera y funciona correctamente. Lea más sobre la confusión de coma flotante y quizás intente con objetos decimales .
fuente
Use la combinación del objeto Decimal y el método round ().
fuente
Para arreglar el punto flotante en lenguajes de tipo dinámico como Python y JavaScript, utilizo esta técnica
También puede usar Decimal de la siguiente manera:
fuente
getcontext().prec = 6
funciona solo para el alcance de la función o para todos los lugares?Resultados:
fuente
fuente
¿Qué pasa con una función lambda como esta:
De esta manera, podrías hacer:
y obten
fuente
Es simple como 1,2,3:
usar decimal módulo para la aritmética rápida de coma flotante decimal correctamente redondeada:
d = Decimal (10000000.0000009)
para lograr el redondeo:
será resultados con
Decimal('10000000.00')
O
PD: crítica de los demás: el formateo no es redondeado.
fuente
Para redondear un número a una resolución, la mejor manera es la siguiente, que puede funcionar con cualquier resolución (0.01 para dos decimales o incluso otros pasos):
fuente
numpy.round
precisión / precisión. Por lo tanto, requiere definirlo como int antes de la multiplicación con resolución. Actualicé el código. ¡Gracias por eso!numpy.float64
resultado de np.round aofloat
simplemente usarloround(value, 2)
. No existe un número IEEE 754 válido entre 13.94999999999999999 (= 1395 / 100.) y 3.950000000000001 (= 1395 * .01). ¿Por qué crees que tu método es el mejor? El valor original 13.949999999999999289 (= value = round (value, 2)) es aún más exacto que su 13.95000000000000178 (impreso por np.float96). Ahora se agrega más información también para numpy a mi respuesta que probablemente desestimó su voto por error. No se trataba de numpy originalmente.int
ti también puedes usar elfloat
ejemplo @szeitlin. Gracias por tu comentario extra. (Lo siento pero no telambda x, n: int (x * 10 n + .5) / 10 n me ha funcionado durante muchos años en muchos idiomas.
fuente
El método que uso es el de corte de cadenas. Es relativamente rápido y simple.
Primero, convierta el flotador en una cadena, luego elija la longitud que le gustaría que fuera.
En la única línea de arriba, convertimos el valor en una cadena, luego mantuvimos la cadena solo en sus primeros cuatro dígitos o caracteres (inclusive).
¡Espero que ayude!
fuente