Tour float x décimales?
Est-il un moyen pour arrondir un python float x décimales? Par exemple:
>>> x = roundfloat(66.66666666666, 4)
66.6667
>>>x = roundfloat(1.29578293, 6)
1.295783
J'ai trouvé des moyens pour découper/tronquer (66.666666666 --> 66.6666), mais pas ronde (66.666666666 --> 66.6667).
Vous devez vous connecter pour publier un commentaire.
Utiliser la fonction intégrée
round()
:de l'aide sur
round()
:Je me sens obligé de fournir un contrepoint à Ashwini Chaudhary de réponse. Malgré les apparences, les deux arguments de la forme de la
round
fonction ne pas autour d'un Python flotteur à un nombre de décimales, et il n'est souvent pas la solution que vous voulez, même si vous pensez qu'il est. Laissez-moi vous expliquer...La capacité à tour, un (Python) flottent à un certain nombre de décimales est quelque chose qui est souvent demandé, mais s'avère être rarement ce qui est réellement nécessaire. La séduisante réponse simple
round(x, number_of_places)
est quelque chose d'attrayant nuisance: il semble comme si il fait ce que vous voulez, mais grâce au fait que Python flotteurs sont stockés à l'intérieur en binaire, c'est de faire quelque chose plutôt subtil. Considérons l'exemple suivant:Avec une naïveté compréhension de ce
round
n', cela semble mal: sûrement, il doit être arrondi jusqu' à52.2
plutôt que bas à52.1
? Pour comprendre pourquoi de tels comportements ne peuvent pas être invoquées, vous devez comprendre que, bien que cela ressemble à un simple décimal décimal de l'opération, c'est loin d'être simple.Donc, voici ce qui est vraiment qui se passe dans l'exemple ci-dessus. (profonde respiration), Nous affichons un décimal représentation de la plus proche binaire nombre à virgule flottante la plus proche
n
chiffres après le point décimal nombre à un binaire à virgule flottante approximation d'un littéral numérique écrit en décimal. Donc, pour obtenir de l'original littéral numérique pour l'affichage de la sortie, le matériel a fait de la quatre séparer les conversions entre le binaire et décimal formats, deux dans chaque direction. Le décomposant (et avec les avertissements habituels à assumer la norme IEEE 754 binary64 format, rond-liens-de-même de l'arrondi et de la norme IEEE 754 règles):D'abord le littéral numérique
52.15
obtient analysés et convertis à un Python flotteur. Le nombre réel de stockage est de7339460017730355 * 2**-47
, ou52.14999999999999857891452847979962825775146484375
.À l'interne comme à la première étape de la
round
opération, Python calcule le plus proche à 1 chiffre après le point décimal de la chaîne pour le numéro en mémoire. Depuis ce numéro est une touche en vertu de la valeur d'origine de52.15
, nous nous retrouvons arrondi vers le bas et d'obtenir une chaîne de52.1
. C'est ce qui explique pourquoi nous sommes en train de52.1
que le résultat final au lieu de52.2
.Puis dans la deuxième étape de la
round
opération, Python tourne cette chaîne dans un flotteur, d'obtenir le plus proche binaire à virgule flottante nombre de52.1
, qui est maintenant7332423143312589 * 2**-47
, ou52.10000000000000142108547152020037174224853515625
.Enfin, dans le cadre de Python read-eval-print loop (REPL), la valeur à virgule flottante est affiché (en décimal). Qui implique la conversion de la valeur binaire de retour pour une chaîne décimale, se
52.1
que la sortie finale.En Python 2.7 et plus tard, nous avons l'agréable situation que les deux conversions à l'étape 3 et 4 de s'annuler les uns les autres. C'est en raison de Python est le choix de
repr
mise en œuvre, qui produit les plus brefs décimal de la valeur de la garantie pour arrondir correctement à la réalité de flotter. Une conséquence de ce choix est que si vous commencez avec tout (pas trop grand, pas trop petit) décimal littérale avec moins de 15 chiffres significatifs alors le correspondant flotteur s'affiche, indiquant ces chiffres:Malheureusement, c'est une continuation de l'illusion que Python est de stocker des valeurs en décimal. Ce n'est pas la version 2.6 de Python, si! Voici l'exemple d'origine exécuté en Python 2.6:
Pas seulement sommes-nous en rond dans la direction opposée, se
52.2
au lieu de52.1
, mais la valeur affichée n'a même pas l'impression que52.2
! Ce comportement a causé de nombreux rapports pour le Python bug tracker le long des lignes de "la ronde est cassé!". Mais ce n'est pasround
qui est cassé, c'est les attentes de l'utilisateur. (Ok, ok,round
est un peu peu cassé dans la version 2.6 de Python, en ce qu'elle n'utilisez pas l'arrondi correct.)Version courte: si vous êtes à l'aide de deux arguments en rond, et on s'attend à un comportement prévisible à partir d'un binaire approximation d'un décimal tour d'un binaire approximation d'un décimal à mi-chemin des cas, vous êtes d'avoir des ennuis.
Donc assez avec les "deux arguments tour est mauvais" argument. Ce devrait - vous à la place? Il y a plusieurs possibilités, en fonction de ce que vous essayez de faire.
Si vous êtes l'arrondissement à des fins d'affichage, alors vous ne voulez pas d'un flotteur de résultat à tous; vous voulez une chaîne de caractères. Dans ce cas, la réponse est d'utiliser la mise en forme de chaîne:
Même alors, on doit être conscient de l'interne de la représentation binaire afin de ne pas être surpris par le comportement de l'apparente décimal à mi-chemin des cas.
Si vous êtes d'exploitation dans un contexte où c'est la direction qui décimal à mi-chemin des cas sont arrondis (par exemple, dans certains contextes financiers), vous pouvez représenter votre nombres à l'aide de la
Decimal
type. Faire un décimal ronde sur leDecimal
type fait beaucoup plus de sens que sur un type binaire (tout aussi, arrondi à un nombre fixe de binaire endroits sens parfait sur un type binaire). En outre, ladecimal
module vous donne un meilleur contrôle du mode d'arrondi. En Python 3,round
fait le travail directement. En Python 2, vous avez besoin de laquantize
méthode.Dans de rares cas, la version à deux arguments de
round
vraiment est ce que vous voulez: vous êtes peut-être binning flotte dans des bacs de taille0.01
, et vous n'avez pas soin particulier à la manière dont de affaires transfrontalières aller. Cependant, ces cas sont rares, et il est difficile de justifier l'existence de la version à deux arguments de laround
builtin fondés sur les cas seul.float
devrait être totalement équivalent à l'utilisation deround
. L'opération de formatage est de nouveau une conversion de binaire en virgule flottante à une chaîne décimale, et c'est en utilisant exactement les mêmes machines sous le capot queround
est à l'aide. (Pour Python 2, c'est un peu différent, parce que la moitié de comportement est différent.)