¿Redondear a dos lugares decimales en Python 2.7?

82

Usando Python 2.7, ¿cómo redondeo mis números a dos lugares decimales en lugar del 10 o menos que da?

print "financial return of outcome 1 =","$"+str(out1)
RCN
fuente
2
Esto podría ser una lata de gusanos. ¿Está almacenando datos financieros en una variable de punto flotante y ahora desea redondearlo? El redondeo exacto no es posible en la mayoría de los casos. Es posible que desee utilizar números enteros o Decimals, según lo que esté intentando hacer realmente.
Tim Pietzcker
Obtenga más información sobre los especificadores de formato. Puede imprimir directamente valores flotantes, sin convertirlos en cadenas.
John Doe

Respuestas:

198

Utilice la función incorporada round():

>>> round(1.2345,2)
1.23
>>> round(1.5145,2)
1.51
>>> round(1.679,2)
1.68

O función incorporada format():

>>> format(1.2345, '.2f')
'1.23'
>>> format(1.679, '.2f')
'1.68'

O formato de cadena de nuevo estilo:

>>> "{:.2f}".format(1.2345)
'1.23
>>> "{:.2f}".format(1.679)
'1.68'

O formato de cadena de estilo antiguo:

>>> "%.2f" % (1.679)
'1.68'

ayuda en round:

>>> print round.__doc__
round(number[, ndigits]) -> floating point number

Round a number to a given precision in decimal digits (default 0 digits).
This always returns a floating point number.  Precision may be negative.
Ashwini Chaudhary
fuente
2
El método de formato de cadena es útil cuando se trabaja con decimales. Por ejemploDecimal("{:.2f}".format(val))
Patch Rick Walsh
@PatchRickWalsh O simplemente Decimal(format(val, '.2f')).
Ashwini Chaudhary
9
¡Frio! No sabía sobre ese formato incorporado. Después de explorar más, creo que esta es la forma más precisa de redondeo si los errores de punto flotante no son absolutamente aceptables: Decimal('123.345').quantize(Decimal('1.00'), rounding=decimal.ROUND_HALF_UP)te da Decimal('123.35'). Por otro lado Decimal(format(Decimal('123.345'), '.2f'))le da Decimal('123.34')porque la representación binaria de 123.345 es menor que 123.345.
Patch Rick Walsh
47

Ya que estás hablando de cifras financieras , NO QUIERES usar aritmética de punto flotante. Es mejor usar Decimal.

>>> from decimal import Decimal
>>> Decimal("33.505")
Decimal('33.505')

Formato de salida de texto con estilo nuevo format()(el valor predeterminado es redondeo medio par):

>>> print("financial return of outcome 1 = {:.2f}".format(Decimal("33.505")))
financial return of outcome 1 = 33.50
>>> print("financial return of outcome 1 = {:.2f}".format(Decimal("33.515")))
financial return of outcome 1 = 33.52

Vea las diferencias en el redondeo debido a la imprecisión del punto flotante:

>>> round(33.505, 2)
33.51
>>> round(Decimal("33.505"), 2)  # This converts back to float (wrong)
33.51
>>> Decimal(33.505)  # Don't init Decimal from floating-point
Decimal('33.50500000000000255795384873636066913604736328125')

Forma adecuada de redondear los valores financieros :

>>> Decimal("33.505").quantize(Decimal("0.01"))  # Half-even rounding by default
Decimal('33.50')

También es común tener otros tipos de redondeo en diferentes transacciones:

>>> import decimal
>>> Decimal("33.505").quantize(Decimal("0.01"), decimal.ROUND_HALF_DOWN)
Decimal('33.50')
>>> Decimal("33.505").quantize(Decimal("0.01"), decimal.ROUND_HALF_UP)
Decimal('33.51')

Recuerde que si está simulando el resultado de la devolución, posiblemente tendrá que redondear en cada período de interés, ya que no puede pagar / recibir fracciones de centavos, ni recibir intereses sobre fracciones de centavos. Para las simulaciones, es bastante común usar el punto flotante debido a las incertidumbres inherentes, pero si lo hace, recuerde siempre que el error está ahí. Como tal, incluso las inversiones de interés fijo pueden diferir un poco en los rendimientos debido a esto.

Ronan Paixão
fuente
5

También puedes usar str.format():

>>> print "financial return of outcome 1 = {:.2f}".format(1.23456)
financial return of outcome 1 = 1.23
TerryA
fuente
4

Al trabajar con centavos / enteros. Te encontrarás con un problema con 115 (como en $ 1,15) y otros números.

Tenía una función que convertiría un Integer en un Float.

...
return float(115 * 0.01)

Eso funcionó la mayor parte del tiempo, pero a veces devolvía algo así 1.1500000000000001.

Así que cambié mi función para volver así ...

...
return float(format(115 * 0.01, '.2f'))

y eso volverá 1.15. No '1.15'o 1.1500000000000001(devuelve un flotante, no una cadena)

Principalmente estoy publicando esto para recordar lo que hice en este escenario, ya que este es el primer resultado en Google.

Teewuane
fuente
Como se señaló en otra respuesta, para los datos financieros use números decimales, no flotantes.
Bruno Le Floch
1
Terminé convirtiendo casi todo en números enteros. Parece ser mucho más fácil trabajar con él. Sin embargo, no estaba haciendo nada que se ocupara de fracciones de centavos.
teewuane
2

Lo mejor, creo, es usar la función format () :

>>> print("financial return of outcome 1 = $ " + format(str(out1), '.2f'))
// Should print: financial return of outcome 1 = $ 752.60

Pero tengo que decir: no use redondeo o formato cuando trabaje con valores financieros.

Thiago Santos
fuente
formatrequiere que no sea una cadena para el formato f. Si no, obtiene un ValueError. El código correcto es: format(out1, '.2f')sin conversión a cadena
danius
2

Cuando usamos la función round (), no dará valores correctos.

puedes comprobarlo usando, round (2.735) y round (2.725)

por favor use

import math
num = input('Enter a number')
print(math.ceil(num*100)/100)
Midhun MM
fuente
Agregue un ejemplo que probó, los resultados y qué cree que está mal en ellos.
Liran Funaro
import math num = input ('Enter a number') numr = float (round (num, 2)) print numr
Midhun MM
1
print "financial return of outcome 1 = $%.2f" % (out1)
John Doe
fuente
0

Una solución alternativa bastante simple es convertir el flotador en cadena primero, seleccionar la subcadena de los primeros cuatro números y finalmente convertir la subcadena de nuevo a flotante. Por ejemplo:

>>> out1 = 1.2345
>>> out1 = float(str(out1)[0:4])
>>> out1

Puede que no sea muy eficiente, pero simple y funciona :)

Shan Niz
fuente
2
Este método es muy poco confiable. Si su valor tiene más de un dígito antes del punto decimal, no obtiene los dos lugares decimales deseados. Mismo problema con un número negativo.
André Kuhlmann
0

Redondeando al siguiente 0.05, haría de esta manera:

def roundup(x):
    return round(int(math.ceil(x / 0.05)) * 0.05,2)
Lucas VL
fuente