144 votes

round() ne semble pas arrondir correctement.

La documentation relative à la round() indique que vous lui passez un nombre, et les positions après la décimale à arrondir. Ainsi, elle devrait faites-le :

n = 5.59
round(n, 1) # 5.6

Mais, en réalité, la bonne vieille bizarrerie de la virgule flottante s'insinue et vous obtenez :

5.5999999999999996

Pour les besoins de l'interface utilisateur, je dois afficher 5.6 . J'ai fait un tour sur Internet et j'ai trouvé quelques documentation que cela dépend de mon implémentation de Python. Malheureusement, cela se produit à la fois sur ma machine de développement Windows et sur chaque serveur Linux que j'ai essayé. Voir aussi ici .

À moins de créer ma propre bibliothèque ronde, y a-t-il un moyen de contourner ce problème ?

4 votes

J'ai essayé avec python 2.7.11 round(5.59) et j'ai obtenu le résultat 5.6 sur les machines Windows et linux x86 64 bit, Cython ? (le lien de documentation mentionné a dû être modifié).

7 votes

Là où ça ne fonctionne pas correctement, c'est round(5.55, 1) = 5.5 .

1 votes

Cela répond-il à votre question ? Limitation des flottants à deux décimales

110voto

Jimmy Points 35501

Je ne peux rien contre la façon dont il est stocké, mais au moins le formatage fonctionne correctement :

'%.1f' % round(n, 1) # Gives you '5.6'

17 votes

J'ai essayé print '%.2f' % 655.665 mais il renvoie 655.66 il devrait être 655.67

1 votes

Voir @Kyrie stackoverflow.com/questions/9301690/ . L'imprécision des virgules flottantes est à blâmer ici -- "5.665 -> 5.67" mais "15.665 -> 15.66". Utilisez des décimales si vous avez besoin d'une précision exacte.

8 votes

Cela fonctionne après une recherche :) from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_DOWN # utilisation pour arrondir les nombres flottants Decimal(str(655.665)).quantize(Decimal('1.11'), rounding=ROUND_HALF_UP) # Problèmes et limites des points flottants

104voto

Vinko Vrsalovic Points 116138

Le formatage fonctionne correctement même sans avoir à arrondir :

"%.1f" % n

19 votes

Selon les docs ce style de formatage des chaînes de caractères finira par disparaître. Le nouveau style de formatage serait "{:.1f}".format(n)

3 votes

Ne s'arrondit pas correctement : '%.5f' % 0.988625 donne 0.98862

0 votes

@schlamar : C'est aussi le comportement de round() : round(0.988625,5) donne aussi 0.98862. round(0.988626,5) ainsi que "%.5f" % 0.988626 donnent 0.98863.

38voto

Si vous utilisez le module Decimal, vous pouvez faire des approximations sans utiliser la fonction "round". Voici ce que j'utilise pour arrondir, en particulier lorsque j'écris des applications monétaires :

from decimal import Decimal, ROUND_UP

Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP)

Cela renvoie un nombre décimal qui est 16,20.

6 votes

C'est la réponse canonique - là où la précision compte, de toute façon, c'est-à-dire à peu près partout. Bien sûr : c'est un peu verbeux . Mais ajoutez cette fonction dans une fonction d'aide et vous êtes prêt à formater et partir.

1 votes

Si vous obtenez cette erreur NameError: global name 'ROUND_UP' is not defined vous devez importer votre fonction d'arrondi : from decimal import Decimal, ROUND_UP . Autres fonctions d'arrondi

2 votes

Votre exemple semble encore dangereux : vous vous fiez à l'arrondi fourni par str().

23voto

Will Harris Points 17002

round(5.59, 1) fonctionne bien. Le problème est que 5,6 ne peut pas être représenté exactement en virgule flottante binaire.

>>> 5.6
5.5999999999999996
>>> 

Comme le dit Vinko, vous pouvez utiliser le formatage des chaînes de caractères pour effectuer des arrondis pour l'affichage.

Python dispose d'un module pour l'arithmétique décimale si vous en avez besoin.

2 votes

Ce n'est plus un problème avec Python 2.7 ou Python 3.5.

18voto

Tomi Kyöstilä Points 743

Vous obtenez '5.6' si vous faites str(round(n, 1)) au lieu de simplement round(n, 1) .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X