¿Cómo redondear a 2 decimales con Python?

254

Estoy obteniendo muchos decimales en la salida de este código (convertidor de Fahrenheit a Celsius).

Mi código actualmente se ve así:

def main():
    printC(formeln(typeHere()))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(answer)
    print "\nYour Celsius value is " + answer + " C.\n"



main()

Entonces mi pregunta es, ¿cómo hago para que el programa redondee cada respuesta al segundo decimal?

Dolcens
fuente
66
Un pequeño comentario sobre tu código. No hay ninguna razón para mantener el valor Fahrenheit como global, es suficiente (y mejor) transmitirlo como parámetro a sus funciones. Entonces, elimine la línea "Fahrenheit global". En la función formeln, cambie el nombre del parámetro a la función "Fahreinheit" formeln (Fahreinheit). En cuanto al redondeo, puede usar los parámetros "%" para mostrar solo los primeros 2 dígitos, y debe redondearse para estos dígitos. No hay ningún efecto en el número de dígitos proporcionados en la fórmula en forma formal.
arieli

Respuestas:

443

Puede usar la roundfunción, que toma como primer argumento el número y el segundo argumento es la precisión después del punto decimal.

En su caso, sería:

answer = str(round(answer, 2))
rolisz
fuente
21
Eso se llama redondeo de los banqueros. Se redondea hacia el número par. Está en el estándar IEEE 754 para números de coma flotante. en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz
37
No estoy seguro de qué indujo a las personas a votar el comentario anterior. Para el registro, el hecho de que round(2.675, 2)da 2.67más que 2.68nada no tiene nada que ver con el redondeo de Banker.
Mark Dickinson
3
nota : esto cambia el valor de la respuesta. Si simplemente desea redondear para mostrar, vaya con la respuesta de @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth
44
@Johnsyweb Lo estoy intentando hoy, años después de la publicación original y parece funcionar como se esperaba. Parece que round () evolucionó con el tiempo. Vea a continuación: ronda (1.379, 2) -> 1.38 ronda (1.372, 2) -> 1.37 ronda (1.375, 2) -> 1.38
NightFurry
82

Usando str.format()la sintaxis para mostrar answer con dos decimales (sin alterar el valor subyacente de answer):

def printC(answer):
    print("\nYour Celsius value is {:0.2f}ºC.\n".format(answer))

Dónde:

  • :introduce la especificación de formato
  • 0 habilita el relleno de cero con signo para los tipos numéricos
  • .2establece la precisión en2
  • f muestra el número como un número de punto fijo
Johnsyweb
fuente
3
Esta es la respuesta más útil de la OMI: ¡mantiene intacto el valor real y es fácil de implementar! ¡Gracias!
BrettJ
No estoy seguro de por qué, pero el formato '{: 0.2f}'. (0.5357706) me da '0.54' (python 3.6)
Noam Peled el
3
@NoamPeled: ¿Por qué no debería? 0.5357...está más cerca de 0.54que 0.53, por lo que redondear a 0.54tiene sentido.
ShadowRanger
"{:0.2f}".format(1.755)-> 1.75 "{:0.2f}".format(1.7551)-> 1.76 - Sin embargo, ambos habrían esperado igualar 1.76.
Janothan
(Versión de Python: 3.6.10)
Janothan
48

La mayoría de las respuestas sugeridas roundo format. rounda veces se redondea y, en mi caso, necesitaba que el valor de mi variable se redondeara hacia abajo y no solo se mostrara como tal.

round(2.357, 2)  # -> 2.36

Encontré la respuesta aquí: ¿Cómo redondeo un número de coma flotante hasta cierto lugar decimal?

import math
v = 2.357
print(math.ceil(v*100)/100)  # -> 2.36
print(math.floor(v*100)/100)  # -> 2.35

o:

from math import floor, ceil

def roundDown(n, d=8):
    d = int('1' + ('0' * d))
    return floor(n * d) / d

def roundUp(n, d=8):
    d = int('1' + ('0' * d))
    return ceil(n * d) / d
s4w3d0ff
fuente
1
He votado: esto es lo que estaba buscando; Me gusta tu trabajo con python-poloniex: D
Skylar Saveland
2
"los valores se redondean al múltiplo más cercano de 10 a la potencia menos n dígitos;" docs.python.org/3/library/functions.html#round así que no, la ronda no siempre se redondea, por ejemploround(2.354, 2) # -> 2.35
Pete Kirkham el
@PeteKirkham tienes razón, edité mi respuesta para tener más sentido y precisión.
s4w3d0ff
2
-0.54 es la respuesta correcta para redondear -0.5357706 hacia abajo porque es un número negativo, -0.54 <
-0.53
2
Yo usaría en 10**dlugar de int('1' + ('0' * d)).
Jonathon Reinhart el
11
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))
Mahadi
fuente
8

Quieres redondear tu respuesta.

round(value,significantDigit)es la solución ordinaria para hacer esto, sin embargo, esto a veces no funciona como cabría esperar desde una perspectiva matemática cuando el dígito inmediatamente inferior (a la izquierda de) el dígito que está redondeando tiene un 5.

Aquí hay algunos ejemplos de este comportamiento impredecible:

>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01

Suponiendo que su intención es hacer el redondeo tradicional para las estadísticas en las ciencias, este es un útil contenedor para que la roundfunción funcione como se espera y necesita importcosas adicionales como Decimal.

>>> round(0.075,2)

0.07

>>> round(0.075+10**(-2*6),2)

0.08

¡Ajá! Entonces, en base a esto, podemos hacer una función ...

def roundTraditional(val,digits):
   return round(val+10**(-len(str(val))-1), digits)

Básicamente, esto agrega un valor realmente pequeño a la cadena para obligarla a redondearse correctamente en las instancias impredecibles donde normalmente no roundfunciona con la función cuando lo espera. Un valor conveniente para agregar es 1e-Xdónde Xestá la longitud de la cadena de números que está tratando de usar rounden más 1.

El enfoque de uso 10**(-len(val)-1)fue deliberado, ya que es el número pequeño más grande que puede agregar para forzar el cambio, al tiempo que garantiza que el valor que agregue nunca cambie el redondeo, incluso si .falta el decimal . Podría usar solo 10**(-len(val))con una condición if (val>1)para restar 1más ... pero es más simple restar siempre, 1ya que eso no cambiará mucho el rango aplicable de números decimales que esta solución puede manejar adecuadamente. Este enfoque fallará si sus valores alcanzan los límites del tipo, fallará, pero para casi todo el rango de valores decimales válidos debería funcionar.

Entonces el código terminado será algo así como:

def main():
    printC(formeln(typeHere()))

def roundTraditional(val,digits):
    return round(val+10**(-len(str(val))-1))

def typeHere():
    global Fahrenheit
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(c):
    Celsius = (Fahrenheit - 32.00) * 5.00/9.00
    return Celsius

def printC(answer):
    answer = str(roundTraditional(answer,2))
    print "\nYour Celsius value is " + answer + " C.\n"

main()

... debería darte los resultados que esperas.

También puede usar la biblioteca decimal para lograr esto, pero el contenedor que propongo es más simple y puede preferirse en algunos casos.


Editar: Gracias Blckknght por señalar que el 5caso marginal ocurre solo para ciertos valores aquí .

Jason R. Mick
fuente
6

Simplemente use el formato con% .2f que le da redondeo a 2 decimales.

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer
Santosh Ghimire
fuente
4

Puede usar el operador de formato de cadena de python "%". "% .2f" significa 2 dígitos después del punto decimal.

def typeHere():
    try:
        Fahrenheit = int(raw_input("Hi! Enter Fahrenheit value, and get it in Celsius!\n"))
    except ValueError:
        print "\nYour insertion was not a digit!"
        print "We've put your Fahrenheit value to 50!"
        Fahrenheit = 50
    return Fahrenheit

def formeln(Fahrenheit):
    Celsius = (Fahrenheit - 32.0) * 5.0/9.0
    return Celsius

def printC(answer):
    print "\nYour Celsius value is %.2f C.\n" % answer

def main():
    printC(formeln(typeHere()))

main()

http://docs.python.org/2/library/stdtypes.html#string-formatting

arieli
fuente
4

Puede usar el operador redondo para hasta 2 decimales

num = round(343.5544, 2)
print(num) // output is 343.55
Asad Manzoor
fuente
3

Puedes usar la función redonda.

round(80.23456, 3)

le dará una respuesta de 80.234

En su caso, use

answer = str(round(answer, 2))

Espero que esto ayude :)

Satyaki Sanyal
fuente
2

Si necesita evitar el problema de punto flotante en los números de redondeo para la contabilidad, puede usar numpy round.

Necesitas instalar numpy:

pip install numpy

y el código:

import numpy as np

print(round(2.675, 2))
print(float(np.round(2.675, 2)))

huellas dactilares

2.67
2.68

Debería usar eso si administra dinero con redondeo legal.

Samuel Dauzon
fuente
1

Aquí hay un ejemplo que usé:

def volume(self):
    return round(pi * self.radius ** 2 * self.height, 2)

def surface_area(self):
    return round((2 * pi * self.radius * self.height) + (2 * pi * self.radius ** 2), 2)
Patrick Hill
fuente
1

No estoy seguro de por qué, pero el formato '{: 0.2f}'. (0.5357706) me da '0.54'. La única solución que funciona para mí (python 3.6) es la siguiente:

def ceil_floor(x):
    import math
    return math.ceil(x) if x < 0 else math.floor(x)

def round_n_digits(x, n):
    import math
    return ceil_floor(x * math.pow(10, n)) / math.pow(10, n)

round_n_digits(-0.5357706, 2) -> -0.53 
round_n_digits(0.5357706, 2) -> 0.53
Noam pelado
fuente
Esto es truncar, no redondear.
ShadowRanger