round float down decimales python floating-point rounding

down - python truncate float



round() en Python no parece estar redondeando correctamente (17)

La documentación para la función round() indica que le pasa un número y las posiciones pasan del decimal al redondeo. Por lo tanto, debe hacer esto:

n = 5.59 round(n, 1) # 5.6

Pero, en realidad, la buena rareza del viejo punto flotante se arrastra y obtienes:

5.5999999999999996

A los efectos de la IU, necesito mostrar 5.6 . Busqué en Internet y encontré documentation que documentation que esto 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. Vea aquí también .

Además de crear mi propia biblioteca redonda, ¿hay alguna forma de evitar esto?


Aquí es donde veo que la ronda falla. ¿Qué pasaría si quisieras redondear estos 2 números a un decimal? 23.45 23.55 Mi educación fue que, al redondearlos, 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.


Código:

x1 = 5.63 x2 = 5.65 print(float(''%.2f'' % round(x1,1))) # gives you ''5.6'' print(float(''%.2f'' % round(x2,1))) # gives you ''5.7''

Salida:

5.6 5.7


Eche un vistazo al módulo Decimal

Decimal "se basa en un modelo de punto flotante diseñado pensando en las personas y necesariamente tiene un principio rector fundamental: las computadoras deben proporcionar una aritmética que funcione de la misma manera que la aritmética que la gente aprende en la escuela". - extracto de la especificación aritmética decimal.

y

Los números decimales se pueden representar exactamente. Por el contrario, los números como 1.1 y 2.2 no tienen una representación exacta en el punto flotante binario. Los usuarios finales normalmente no esperarían que 1.1 + 2.2 se muestre como 3.3000000000000003 como lo hace con el punto flotante binario.

Decimal proporciona el tipo de operaciones que facilitan la escritura de aplicaciones que requieren operaciones de punto flotante y también deben presentar esos resultados en un formato legible para las personas, por ejemplo, la contabilidad.


El formateo funciona correctamente incluso sin tener que redondear:

"%.1f" % n


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.

import re def custom_round(num, precision): # Get the type of given number type_num = type(num) # If the given type is not a valid number type, raise TypeError if type_num not in [int, float, Decimal]: raise TypeError("type {} doesn''t define __round__ method".format(type_num.__name__)) # If passed number is int, there is no rounding off. if type_num == int: return num # Convert number to string. str_num = str(num) # Get the precision of the given number. num_precision = len(str_num.split(''.'')[1]) # Rounding off is done only if number precision is # greater than requested precision if num_precision <= precision: return num # Replace the last ''5'' with 6 so that rounding off returns desired results if str_num[-1] == ''5'': str_num = re.sub(''5$'', ''6'', str_num) return round(type_num(str_num), precision)


Es un gran problema de hecho. Pruebe este código:

print "%.2f" % (round((2*4.4+3*5.6+3*4.4)/8,2),)

Muestra 4.85. Entonces lo haces:

print "Media = %.1f" % (round((2*4.4+3*5.6+3*4.4)/8,1),)

y muestra 4.8. ¿Cálculos a mano la respuesta exacta es 4.85, pero si intenta:

print "Media = %.20f" % (round((2*4.4+3*5.6+3*4.4)/8,20),)

puedes ver la verdad: el punto flotante se almacena como la suma finita más cercana de fracciones cuyos denominadores son potencias de dos.


Estoy haciendo:

int(round( x , 0))

En este caso, primero redondeamos apropiadamente a nivel de unidad, luego convertimos a entero para evitar imprimir un flotador.

asi que

>>> int(round(5.59,0)) 6

Creo que esta respuesta funciona mejor que formatear la cadena, y también me hace más sentido usar la función circular.


Funciona perfecto

format(5.59, ''.1f'') # to display float(format(5.59, ''.1f'')) #to round


La matemática de coma flotante es vulnerable a ligeras, pero molestas, imprecisiones de precisión. Si puede trabajar con un número entero o punto fijo, se le garantizará precisión.


Obtienes ''5.6'' si haces str(round(n, 1)) lugar de round(n, 1) .


Puede cambiar el tipo de datos a un número entero:

>>> n = 5.59 >>> int(n * 10) / 10.0 5.5 >>> int(n * 10 + 0.5) 56

Y luego, muestre el número insertando el separador decimal de la configuración regional.

Sin embargo, la respuesta de Jimmy es mejor.


Puede usar el operador de formato de cadena % , similar a sprintf.

mystring = "%.2f" % 5.5999


Qué pasa:

round(n,1)+epsilon


Si usa el módulo Decimal puede aproximar sin el uso de la función ''ronda''. Esto es lo que he estado usando para redondear, especialmente cuando escribo aplicaciones monetarias:

Decimal(str(16.2)).quantize(Decimal(''.01''), rounding=ROUND_UP)

Esto devolverá un Número decimal que es 16.20.


no puede ayudar a la forma en que se almacena, pero al menos el formato funciona correctamente:

''%.1f'' % round(n, 1) # gives you ''5.6''


round(5.59, 1) funciona bien. El problema es que 5.6 no se puede representar exactamente en el punto flotante binario.

>>> 5.6 5.5999999999999996 >>>

Como dice Vinko, puede usar el formato de cadena para hacer el redondeo para visualizar.

Python tiene un módulo para aritmética decimal si lo necesita.


printf el lechón.

print ''%.1f'' % 5.59 # returns 5.6