32 votes

Pourquoi les langages de programmation arrondissent-ils jusqu'à 0,6?

Si vous mettez une virgule dans un format où doit être arrondi à la 10e, et c'est: 1.55, il va tour à 1,5. 1.56 sera ensuite le tour de 1.6. À l'école, je me souviens d'apprentissage autour de vous lorsque vous atteignez cinq, et vers le bas si c'est 4 ou ci-dessous. Pourquoi est-il différent en Python, et al.

Voici un exemple de code pour Python 2.6 x (quelle que soit la version la plus récente)

'{0:01.2f}'.format(5.555)  # This will return '5.55'

Après avoir essayé certains de ces exemples, j'ai réalisé quelque chose d'encore plus de confusion:

'{0:01.1f}'.format(5.55)  # This will return '5.5'
# But then
'{0:01.1f}'.format(1.55)  # This will return '1.6'

Pourquoi la différence lors de l'utilisation de 1,55 vs 5.55. Les deux sont typés comme des littéraux (donc flotteurs)

85voto

Stephen Canon Points 58003

Tout d'abord, dans la plupart des langues, un non constante comme "1.55" est considéré comme un double de la valeur de précision. Cependant, 1.55 n'est pas exactement représentable comme un double de la précision de la valeur, car il ne dispose pas d'une résiliation de la représentation en binaire. Cela provoque beaucoup de curieux comportements, mais l'un des effets est que lorsque vous tapez 1.55, vous n'avez pas réellement obtenir la valeur qui est exactement à mi-chemin entre 1.5 et 1.6.

En binaire, le nombre décimal 1.55 est:

1.10001100110011001100110011001100110011001100110011001100110011001100...

Lorsque vous tapez "1.55", cette valeur est arrondie à l'unité la plus proche représentable valeur à double précision (sur beaucoup de systèmes,... mais il y a des exceptions, sur lequel je reviendrai). Cette valeur est:

1.1000110011001100110011001100110011001100110011001101

ce qui est légèrement plus grand que 1.55; en décimal, c'est exactement:

1.5500000000000000444089209850062616169452667236328125

Donc, lorsqu'on a demandé à la ronde de cette valeur à un seul chiffre après la virgule, il sera tour jusqu' à 1.6. C'est pourquoi la plupart des commentateurs ont dit qu'ils ne peuvent pas reproduire le comportement que vous voyez.

Mais attendez, sur votre système, "1.55" arrondi vers le bas, pas vers le haut. Ce qui se passe?

Il pourrait être un peu différente des choses, mais le plus probable, c'est que vous êtes sur une plate-forme (probablement Windows), qui est par défaut à faire de l'arithmétique à virgule flottante à l'aide de x87 instructions, qui utilisent différents (80 bits) format interne. Dans les années 80 bits format de 1,55 a de la valeur:

1.100011001100110011001100110011001100110011001100110011001100110

ce qui est légèrement plus petite que 1.55; en décimal, ce nombre est:

1.54999999999999999995663191310057982263970188796520233154296875

Parce que c'est juste plus petit que 1.55, il arrondit vers le bas quand il est arrondi à un chiffre après la virgule, donner le résultat "1.5" que vous êtes en train d'observer.

FWIW: dans la plupart des langages de programmation, le mode d'arrondi par défaut est en fait "tour la plus proche, des liens même". C'est juste que lorsque vous spécifiez des valeurs fractionnaires en décimal, vous aurez presque jamais frappé exactement à mi-chemin des cas, de sorte qu'il peut être difficile pour un profane d'observer cela. Vous pouvez le voir, cependant, si vous regardez comment "1.5" est arrondie à zéro chiffres:

>>> "%.0f" % 0.5
'0'
>>> "%.0f" % 1.5
'2'

Il est à noter que les valeurs rondes de même des chiffres, ni des tours à "1".

Edit: dans votre nouvelle question, vous semblez avoir changé d'interpréteur python, sur lequel virgule flottante est fait dans le IEEE754 de type double, pas le x87 80bit type. Ainsi, "à 1,55" tours jusqu', comme dans mon premier exemple, mais "5.55" convertit à la suite binaire à virgule flottante valeur:

101.10001100110011001100110011001100110011001100110011

ce qui est exactement:

5.54999999999999982236431605997495353221893310546875

en décimal; puisqu'il est plus petit que 5.55, il arrondit vers le bas.

5voto

Martin Liversage Points 43712

Il y a plusieurs façons d'arrondir les nombres. Vous pouvez en savoir plus sur les arrondis sur Wikipedia . La méthode d'arrondi utilisée dans Python correspond à Arrondir à moitié de zéro et la méthode d'arrondi que vous décrivez est à peu près la même (du moins pour les nombres positifs).

2voto

Dave Webb Points 90034

Pouvez-vous donner un exemple de code, car ce n'est pas le comportement que je vois dans Python:

 >>> "%.1f" % 1.54
'1.5'
>>> "%.1f" % 1.55
'1.6'
>>> "%.1f" % 1.56
'1.6'
 

2voto

Travis Bradshaw Points 2255

Cela ne semble pas être le cas. Vous utilisez le formateur de chaîne "float", non?

 >>> "%0.2f" % 1.55
'1.55'
>>> "%0.1f" % 1.55
'1.6'
>>> "%0.0f" % 1.55
'2'
 

2voto

Ed Altorfer Points 3392

D'arrondi et de troncature est différent pour chaque langage de programmation, de sorte que votre question est probablement directement liée à Python.

Cependant, arrondi comme une pratique dépend de votre méthode.

Vous devriez également savoir que la CONVERSION d'un nombre décimal en un nombre entier dans de nombreux langages de programmation, les rendements des résultats différents de fait en arrondissant ce nombre.

Edit: Par certains des autres affiches, il semble que Python ne présentent pas de l'arrondissement de comportement que vous avez décrit:

>>> "%0.2f" % 1.55 
'1.55' 
>>> "%0.1f" % 1.55 
'1.6' 
>>> "%0.0f" % 1.55 
'2' 

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