2010-02-01 6 views
10

J'ai rencontré un problème très étrange en python. (L'utilisation 2.4.x python)Problème d'arrondi Python

Dans les fenêtres:

>>> a = 2292.5 
>>> print '%.0f' % a 
2293 

Mais dans Solaris:

>>> a = 2292.5 
>>> print '%.0f' % a 
2292 

Mais c'est le même dans les deux fenêtres et solaris:

>>> a = 1.5 
>>> print '%.0f' % a 
2 

Quelqu'un peut-il expliquer ce comportement? Je suppose que c'est dépendante de la façon dont python a été compilé?

+0

Notez que si vous voulez toujours obtenir l'intuitif « rond loin de zéro "comportement, vous pouvez utiliser la fonction C99/POSIX.1-2001" roundf ". Je ne suis pas sûr s'il y a des bindings pour cela en Python, ou si c'est disponible du tout dans Windows; Si c'est important pour vous, vous pouvez facilement écrire un module C pour y inclure une implémentation tierce. –

Répondre

10

La fonction responsable de l'exécution de ce formatage est PyOS_snprintf (voir the sources). Comme vous le supposez, c'est malheureusement dépendant du système, c'est-à-dire vsprintf, vsnprintf ou d'autres fonctions similaires fournies par la bibliothèque d'exécution C de la plate-forme (je ne me souviens pas si la norme C dit quelque chose sur le '% f' formatage pour les flottants qui sont "exactement à mi-chemin" entre deux valeurs arrondies possibles ... mais, si le standard C est laxiste à ce sujet, ou plutôt le standard C est strict mais certains runtimes C le cassent, finalement c'est un problème assez académique. .).

+3

Je crois que certaines implémentations (de C) arrondissent vers le bas lorsque le chiffre précédent est pair et arrondi vers le haut quand il est impair –

+0

gnibbler - vous venez de me dire –

+1

@gnibbler, c'est une bonne règle comptable (même mandatée par la loi dans certaines juridictions , Je pense) - mais la comptabilité est invariablement effectuée avec des nombres basés sur la décimale, ** pas ** des flottants binaires, donc dans le contexte des flottants cela devient un peu discutable ;-). –

0

I dépend de la plateforme. Vous pouvez trouver la documentation here.

Il est bon d'utiliser ceil ou floor lorsque vous savez ce que vous voulez (arrondir à la hausse ou à la baisse).

2

round() arrondit vers le plus proche entier pair
"% n.nf" fonctionne de la même manière que ronde()
int() tronque vers zéro

« arrondir un nombre positif entier le plus proche
peut être mis en œuvre en ajoutant 0,5 et tronquer »
- http://en.wikipedia.org/wiki/Rounding

en Python, vous pouvez le faire avec: math.trunc(n + 0.5)
en supposant n est positif o f bien sûr ...

Où « un demi-tour à même » ne convient pas, je l'utilise maintenant
math.trunc(n + 0.5) où je l'habitude d'utiliser int(round(n))

+0

En fait, python ne tourne pas vers l'entier pair le plus proche: 'si deux multiples sont proches, l'arrondi s'éloigne de 0 (par exemple, round (0.5) vaut 1.0 et round (-0.5) vaut -1.0) . »[doc] (http://docs.python.org/2/library/functions.html#round) – ford