web-dev-qa-db-fra.com

Comment arrondir un nombre à virgule flottante jusqu'à une certaine décimale?

Supposons que j'ai 8.8333333333333339 et que je souhaite le convertir en 8.84. Comment puis-je accomplir cela en Python?

round(8.8333333333333339, 2) donne 8.83 et non 8.84. Je suis nouveau sur Python ou sur la programmation en général.

Je ne veux pas l'imprimer comme une chaîne, et le résultat sera utilisé plus tard. Pour plus d'informations sur le problème, veuillez vérifier Python de Tim Wilson: astuces de programmation: Calculateur de prêt et de paiement .

77
hsinxh

8.833333333339 (ou 8.833333333333334, le résultat de 106.00/12) correctement arrondi à deux décimales est 8.83. Mathématiquement, cela ressemble à ce que vous voulez, c'est un ceiling function . Celui du module math de Python est nommé ceil :

import math

v = 8.8333333333333339
print(math.ceil(v*100)/100)  # -> 8.84

Respectivement, les fonctions de plancher et de plafond mappent généralement un nombre réel au plus grand entier précédent ou au plus petit nombre entier suivant, qui n'a pas de décimales. Ainsi, pour les utiliser pour 2 décimales, le nombre est d'abord multiplié par 10.2 (ou 100) pour décaler le point décimal et est ensuite divisé par celui-ci pour compenser.

Si vous ne voulez pas utiliser le module math pour une raison quelconque, vous pouvez utiliser cette implémentation (testée au minimum) que je viens d'écrire:

def ceiling(x):
    n = int(x)
    return n if n-1 < x <= n else n+1

Comment cela s’applique au lié problème de calculateur de prêt et de paiement

screenshot of loan calculator output

D'après l'exemple de sortie, il apparaît qu'ils arrondis le paiement mensuel, ce que beaucoup appellent l'effet de la fonction de plafond . Cela signifie que chaque mois un peu plus que 1/12 du montant total est payé. Le paiement final a donc été légèrement réduit, ce qui ne laisse qu'un solde impayé de 8.76.

Il aurait été également valable d’utiliser l’arrondissement normal pour obtenir un paiement mensuel de 8.83 et un paiement final légèrement supérieur de 8.87. Cependant, dans le monde réel, les gens n'aiment généralement pas voir leurs paiements augmenter. Il est donc pratique courante d'arrondir chaque paiement: il retourne également l'argent au prêteur plus rapidement.

97
martineau

Ceci est normal (et n'a rien à voir avec Python) car 8.83 ne peut pas être représenté exactement comme un flottant binaire, tout comme 1/3 ne peut pas être représenté exactement en décimal (0.333333 ... à l'infini).

Si vous voulez assurer une précision absolue, vous avez besoin du module decimal :

>>> import decimal
>>> a = decimal.Decimal("8.833333333339")
>>> print(round(a,2))
8.83
64
Tim Pietzcker

Vous souhaitez utiliser le module décimal, mais vous devez également spécifier le mode d'arrondi. Voici un exemple:

>>> import decimal
>>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_UP)
Decimal('8.34')
>>> decimal.Decimal('8.333333').quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN)
Decimal('8.33')
>>> 
22
casevh

Une méthode beaucoup plus simple consiste simplement à utiliser la fonction round (). Voici un exemple.

total_price = float()
price_1 = 2.99
price_2 = 0.99
total_price = price_1 + price_2

Si vous deviez imprimer total_price maintenant, vous auriez

3.9800000000000004

Mais si vous l'incluez dans une fonction round () comme si

print(round(total_price,2))

La sortie est égale à

3.98

La fonction round () fonctionne en acceptant deux paramètres. Le premier est le nombre que vous souhaitez arrondir. La seconde est le nombre de décimales à arrondir.

11
user2252471

Si vous arrondissez 8,8333333333339 à 2 décimales, la bonne réponse est 8,83 et non 8,84. La raison pour laquelle vous avez obtenu 8.83000000001 est parce que 8.83 est un nombre qui ne peut pas être correctement reproduit en binaire et vous donne le plus proche. Si vous souhaitez l’imprimer sans les zéros, procédez comme indiqué par VGE:

print "%.2f" % 8.833333333339   #(Replace number with the variable?)
7

Si vous voulez arrondir, 8.84 est la réponse incorrecte. 8.833333333333 arrondi est 8.83 pas 8.84. Si vous voulez toujours arrondir, vous pouvez utiliser math.ceil. Faites les deux en combinaison avec le formatage de chaîne, car arrondir un nombre flottant n'a pas de sens.

"%.2f" % (math.ceil(x * 100) / 100)
5
Rosh Oxymoron

Le moyen le plus simple de procéder consiste à utiliser la fonction ci-dessous, intégrée:

format()

Par exemple:

format(1.242563,".2f")

La sortie serait:

1.24

De même:

format(9.165654,".1f")

donnerait:

9.2
4
sai surya madhav

Juste pour info. Vous pouvez le faire de cette façon:

def roundno(no):
    return int(no//1 + ((no%1)/0.5)//1)

Là, pas besoin d'inclusions/importations

3
twohot
1
orip

Voici ma solution pour le problème d'arrondir/descendre

< .5  round down

> = .5  round up

import math

def _should_round_down(val: float):
    if val < 0:
        return ((val * -1) % 1) < 0.5
    return (val % 1) < 0.5

def _round(val: float, ndigits=0):
    if ndigits > 0:
        val *= 10 ** (ndigits - 1)
    is_positive = val > 0
    tmp_val = val
    if not is_positive:
        tmp_val *= -1
    rounded_value = math.floor(tmp_val) if _should_round_down(val) else math.ceil(tmp_val)
    if not is_positive:
        rounded_value *= -1
    if ndigits > 0:
        rounded_value /= 10 ** (ndigits - 1)
    return rounded_value

# test
# nr = 12.2548
# for digit in range(0, 4):
#     print("{} decimals : {} -> {}".format(digit, nr, _round(nr, digit)))

# output
# 0 decimals : 12.2548 -> 12
# 1 decimals : 12.2548 -> 12.0
# 2 decimals : 12.2548 -> 12.3
# 3 decimals : 12.2548 -> 12.25
1
opra

Voici une fonction simple pour le faire pour vous:

def precision(num,x):
    return "{0:.xf}".format(round(num))

Ici, num est le nombre décimal. x est la décimale jusqu'à l'endroit où vous voulez arrondir un nombre flottant.

L'avantage par rapport à d'autres implémentations est qu'il peut remplir des zéros à l'extrémité droite de la virgule pour créer un nombre déciaml allant jusqu'à x décimales.

Exemple 1:

precision(10.2, 9)

reviendra

10.200000000 (jusqu'à 9 décimales)

Exemple 2:

precision(10.2231, 2)

reviendra

10.22 (jusqu'à deux décimales)

0
Akash Kandpal

J'ai ce code:

tax = (tax / 100) * price

et puis ce code:

tax = round((tax / 100) * price, 2)

rond a travaillé pour moi

0
Nic56