Comment arrondir à 2 décimales avec Python?

254

Je reçois beaucoup de décimales dans la sortie de ce code (convertisseur Fahrenheit en Celsius).

Mon code ressemble actuellement à ceci:

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()

Donc ma question est, comment puis-je faire le programme autour de chaque réponse à la 2ème décimale?

Dolcens
la source
6
Une petite remarque concernant votre code. Il n'y a aucune raison de conserver la valeur Fahrenheit en tant que global, il suffit (et mieux) de la transmettre en paramètre à vos fonctions. Supprimez donc la ligne "Fahrenheit global". Dans la fonction formeln, renommez le paramètre en fonction "Fahreinheit" formeln (Fahreinheit). Quant à l'arrondi, vous pouvez simplement utiliser les paramètres "%" pour afficher uniquement les 2 premiers chiffres, et il doit être arrondi pour ces chiffres. Il n'y a aucun effet sur le nombre de chiffres fournis dans la formule dans formeln.
arieli

Réponses:

443

Vous pouvez utiliser la roundfonction, qui prend comme premier argument le nombre et le deuxième argument est la précision après le point décimal.

Dans votre cas, ce serait:

answer = str(round(answer, 2))
rolisz
la source
21
C'est ce qu'on appelle l'arrondissement des banquiers. Il arrondit vers le nombre pair. C'est dans la norme IEEE 754 pour les nombres à virgule flottante. en.wikipedia.org/wiki/Rounding#Round_half_to_even
rolisz
37
Je ne sais pas ce qui a poussé les gens à voter pour le commentaire ci-dessus. Pour mémoire, le fait que round(2.675, 2)donne 2.67plutôt que 2.68n'a rien à voir avec l'arrondissement bancaire.
Mark Dickinson
3
remarque : cela change la valeur de la réponse. Si vous voulez simplement arrondir pour l'affichage, allez avec la réponse de @Johnsyweb - stackoverflow.com/a/20457284/1498405
hardmooth
4
@Johnsyweb Je l'essaie aujourd'hui, un an après le message d'origine et il semble fonctionner comme prévu. Il semble que round () ait évolué avec le temps. Voir ci-dessous: ronde (1.379, 2) -> 1.38 ronde (1.372, 2) -> 1.37 ronde (1.375, 2) -> 1.38
NightFurry
82

Utilisation de str.format()la syntaxe de pour afficher answer avec deux décimales (sans modifier la valeur sous-jacente de answer):

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

Où:

  • :introduit la spécification de format
  • 0 active le remplissage nul sensible aux signes pour les types numériques
  • .2définit la précision sur2
  • f affiche le nombre sous forme de nombre à virgule fixe
Johnsyweb
la source
3
C'est la réponse la plus utile de l'OMI - conserve la valeur réelle intacte et est simple à mettre en œuvre! Merci!
BrettJ
Je ne sais pas pourquoi, mais le format '{: 0.2f}'. (0.5357706) me donne '0.54' (python 3.6)
Noam Peled
3
@NoamPeled: Pourquoi pas? 0.5357...est plus proche 0.54que de 0.53, donc arrondir à 0.54est logique.
ShadowRanger
"{:0.2f}".format(1.755)-> 1,75 "{:0.2f}".format(1.7551)-> 1,76 - Cependant, je m'attendrais tous les deux à 1,76.
Janothan
(Version Python: 3.6.10)
Janothan
48

La plupart des réponses suggèrent roundou format. roundarrondit parfois, et dans mon cas, j'avais besoin que la valeur de ma variable soit arrondie et pas seulement affichée comme telle.

round(2.357, 2)  # -> 2.36

J'ai trouvé la réponse ici: comment arrondir un nombre à virgule flottante jusqu'à une certaine décimale?

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

ou:

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
la source
1
J'ai voté positivement - c'est ce que je cherchais; J'aime ton travail avec python-poloniex: D
Skylar Saveland
2
"les valeurs sont arrondies au multiple de 10 le plus proche de la puissance moins les chiffres;" docs.python.org/3/library/functions.html#round donc non, l'arrondi ne s'arrête pas toujours, par exempleround(2.354, 2) # -> 2.35
Pete Kirkham
@PeteKirkham vous avez raison, j'ai édité ma réponse pour avoir plus de sens et de précision.
s4w3d0ff
2
-0,54 est la bonne réponse pour arrondir -0,5357706 vers le bas car il s'agit d'un nombre négatif, -0,54 <-0,53
s4w3d0ff
2
J'utiliserais 10**dau lieu de int('1' + ('0' * d)).
Jonathon Reinhart
11
float(str(round(answer, 2)))
float(str(round(0.0556781255, 2)))
Mahadi
la source
8

Vous voulez arrondir votre réponse.

round(value,significantDigit)est la solution ordinaire pour ce faire, mais cela ne fonctionne parfois pas comme on pourrait s'y attendre d'un point de vue mathématique lorsque le chiffre immédiatement inférieur (à gauche de) le chiffre auquel vous arrondissez a un5 .

Voici quelques exemples de ce comportement imprévisible:

>>> 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

En supposant que votre intention est de faire l'arrondi traditionnel pour les statistiques dans les sciences, c'est un wrapper pratique pour faire roundfonctionner la fonction comme prévu, nécessitant importdes choses supplémentaires comme Decimal.

>>> round(0.075,2)

0.07

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

0.08

Ah! Donc, sur cette base, nous pouvons faire une fonction ...

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

Fondamentalement, cela ajoute une très petite valeur à la chaîne pour la forcer à arrondir correctement sur les instances imprévisibles où elle n'est pas normalement avec la roundfonction lorsque vous vous y attendez. Une valeur pratique à ajouter est 1e-XXest la longueur de la chaîne numérique que vous essayez d'utiliser roundsur plus 1.

L'approche de l'utilisation a 10**(-len(val)-1)été délibérée, car c'est le plus grand petit nombre que vous pouvez ajouter pour forcer le décalage, tout en garantissant que la valeur que vous ajoutez ne change jamais l'arrondi même si la décimale .est manquante. Je pourrais utiliser juste 10**(-len(val))avec une conditionnelle if (val>1)pour soustraire 1plus ... mais il est plus simple de toujours soustraire 1car cela ne changera pas beaucoup la plage applicable de nombres décimaux que cette solution de contournement peut gérer correctement. Cette approche échouera si vos valeurs atteignent les limites du type, cela échouera, mais pour presque toute la plage de valeurs décimales valides, cela devrait fonctionner.

Ainsi, le code fini sera quelque chose comme:

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()

... devrait vous donner les résultats que vous attendez.

Vous pouvez également utiliser la bibliothèque décimale pour accomplir cela, mais le wrapper que je propose est plus simple et peut être préféré dans certains cas.


Edit: Merci Blckknght d' avoir souligné que le 5cas de frange ne se produit que pour certaines valeurs ici .

Jason R. Mick
la source
6

Utilisez simplement la mise en forme avec% .2f qui vous donne un arrondi à 2 décimales.

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

Vous pouvez utiliser l'opérateur de formatage de chaîne de python "%". "% .2f" signifie 2 chiffres après la virgule décimale.

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
la source
4

Vous pouvez utiliser l' opérateur rond jusqu'à 2 décimales

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

Vous pouvez utiliser la fonction ronde.

round(80.23456, 3)

vous donnera une réponse de 80,234

Dans votre cas, utilisez

answer = str(round(answer, 2))

J'espère que cela t'aides :)

Satyaki Sanyal
la source
2

Si vous devez éviter le problème de virgule flottante sur les nombres arrondis pour la comptabilité, vous pouvez utiliser le nombre arrondi.

Vous devez installer numpy:

pip install numpy

et le code:

import numpy as np

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

impressions

2.67
2.68

Vous devriez l'utiliser si vous gérez l'argent avec des arrondis légaux.

Samuel Dauzon
la source
1

Voici un exemple que j'ai utilisé:

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
la source
1

Je ne sais pas pourquoi, mais le format '{: 0.2f}' (0.5357706) me donne '0.54'. La seule solution qui fonctionne pour moi (python 3.6) est la suivante:

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 Peled
la source
C'est tronquer, pas arrondir.
ShadowRanger
0

Comme vous voulez votre réponse en nombre décimal, vous n'avez donc pas besoin de transtyper votre variable de réponse en str dans la fonction printC ().

puis utilisez la mise en forme des chaînes de style printf

codiacTushki
la source