Comment puis-je arrondir un nombre à la deuxième décimale en python? Par exemple:
0.022499999999999999
Doit arrondir à 0.03
0.1111111111111000
Doit arrondir à 0.12
S'il y a une valeur dans la troisième décimale, je veux qu'elle arrondisse toujours en me laissant 2 valeurs derrière la virgule.
Python inclut la fonction round()
qui vous permet de spécifier le nombre de chiffres souhaité. De la documentation:
round(x[, n])
Renvoie la valeur en virgule flottante x arrondie à n chiffres après le point décimal. Si n est omis, la valeur par défaut est zéro. Le résultat est un nombre à virgule flottante. Les valeurs sont arrondies au multiple le plus proche de 10 à la puissance moins n; si deux multiples sont également proches l'un de l'autre, l'arrondi est fait à partir de 0 (par exemple, arrondi (0.5) vaut 1.0 et arrondi (-0.5) vaut -1.0).
Donc, vous voudriez utiliser round(x, 2)
pour arrondir normalement. Pour vous assurer que le nombre est toujours arrondi , vous devez utiliser la fonction ceil(x)
. De même, pour arrondir vers le bas , utilisez floor(x)
.
from math import ceil
num = 0.1111111111000
num = ceil(num * 100) / 100.0
Voir:math.ceil
documentationround
documentation - Vous voudrez probablement le vérifier quand même pour référence future
Extrapolant à partir de la réponse d'Edwin:
from math import ceil, floor
def float_round(num, places = 0, direction = floor):
return direction(num * (10**places)) / float(10**places)
Utiliser:
>>> float_round(0.21111, 3, ceil) #round up
>>> 0.212
>>> float_round(0.21111, 3) #round down
>>> 0.211
>>> float_round(0.21111, 3, round) #round naturally
>>> 0.211
x = math.ceil(x * 100.0) / 100.0
Cela dépend du comportement que vous voulez lorsque vous considérez des nombres positifs et négatifs, mais si vous voulez quelque chose qui arrondit toujours à une valeur plus grande (par exemple, 2.0449 -> 2.05, -2.0449 -> -2.04), vous pouvez alors:
round(x + 0.005, 2)
ou un petit amateur:
def round_up(x, place):
return round(x + 5 * 10**(-1 * (place + 1)), place)
Cela semble aussi fonctionner comme suit:
round(144, -1)
# 140
round_up(144, -1)
# 150
round_up(1e308, -307)
# 1.1e308
Notez que l'astuce ceil(num * 100) / 100
plantera certaines entrées dégénérées, comme 1e308. Cela peut ne pas arriver souvent, mais je peux vous dire que cela ne m'a coûté que quelques jours. Pour éviter cela, "ça serait bien si" ceil()
et floor()
prenaient un argument de décimales, comme (round()
fait ... Pendant ce temps, Quelqu'un connaît-il une alternative propre qui ne plantera pas sur des entrées de ce type? J'avais quelques espoirs pour le paquet decimal
mais il semble mourir aussi:
>>> from math import ceil
>>> from decimal import Decimal, ROUND_DOWN, ROUND_UP
>>> num = 0.1111111111000
>>> ceil(num * 100) / 100
0.12
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
0.12
>>> num = 1e308
>>> ceil(num * 100) / 100
Traceback (most recent call last):
File "<string>", line 301, in runcode
File "<interactive input>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
>>> float(Decimal(num).quantize(Decimal('.01'), rounding=ROUND_UP))
Traceback (most recent call last):
File "<string>", line 301, in runcode
File "<interactive input>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
Bien sûr, on pourrait dire que planter est le seul comportement sain sur de telles entrées, mais je dirais que ce n’est pas l’arrondi, mais la multiplication qui cause le problème (c’est pourquoi, par exemple, 1e306 ne plante pas), et une mise en œuvre plus propre de la ronde de la n-place fn éviterait le hack de la multiplication.
def round_up(number, ndigits=None):
# start by just rounding the number, as sometimes this rounds it up
result = round(number, ndigits if ndigits else 0)
if result < number:
# whoops, the number was rounded down instead, so correct for that
if ndigits:
# use the type of number provided, e.g. float, decimal, fraction
Numerical = type(number)
# add the digit 1 in the correct decimal place
result += Numerical(10) ** -ndigits
# may need to be tweaked slightly if the addition was inexact
result = round(result, ndigits)
else:
result += 1 # same as 10 ** -0 for precision of zero digits
return result
assert round_up(0.022499999999999999, 2) == 0.03
assert round_up(0.1111111111111000, 2) == 0.12
assert round_up(1.11, 2) == 1.11
assert round_up(1e308, 2) == 1e308
La fonction python round
pourrait arrondir ce qui ne vous attend pas.
Vous pouvez être plus précis sur la méthode d'arrondi en utilisant Decimal.quantize
par exemple.
from decimal import Decimal, ROUND_HALF_UP
res = Decimal('0.25').quantize(Decimal('0.0'), rounding=ROUND_HALF_UP)
print(res)
# prints 0.3
Plus de référence:
La fonction ronde indiquée ne fonctionne pas pour les entiers définis tels que:
a = 8
tour (a, 3)
8.0
a = 8.00
tour (a, 3)
8.0
a = 8.000000000000000000000000
tour (a, 3)
8.0
mais, travaille pour:
r = 400/3,0
r
133.33333333333334
round (r, 3)
133.333
De plus, les décimales telles que 2,675 sont arrondies à 2,67 et non 2,68.
Mieux vaut utiliser l’autre méthode décrite ci-dessus.