Lorsque j'exécute ces 2 lignes, je reçois 2 résultats différents. - Pourquoi?
La variable d'élément est un type numpy.float32 p> sortie: p> Je soupçonne que c'est Être lié au type numpy.float32 en quelque sorte? p> Si j'essaie de convertir le numpy.float32 en float I Obtenir ceci: p> 0.0006000000284984708
4 Réponses :
Je ne peux pas sembler trouver la logique dans ce cas, mais j'ai fait une solution de contournement convertir simplement le numpy.float32 code> en float code> et arrondi les chiffres à une décimale spécifique. < / p>
C'est "parce que" un numéro de point flottant de 32 bits ne peut pas représenter 0,006 exactement, la valeur la plus proche est celle que vous voyez lorsque vous coerce à un flotteur 64 bits (c'est-à-dire en faisant float (article) code>, comme python a 64 bits flottants nativement). Beaucoup plus de détails ici: docs.python.org/3/taturial/floatingpoint.html a>
Ce que vous observez malheureusement n'est pas évitable. Cela concerne la représentation interne d'un numéro de flotteur. Dans ce cas, il n'a même pas à voir avec les problèmes de calcul, comme suggéré dans des commentaires ici.
(base binaire) Les nombres de flottaisons utilisés par la plupart des langues sont représentés comme Donc, pour votre question, la manipose c'est plus important. Comme dit c'est comme un tableau de bit. Dans un bit d'octet, un bit a une valeur en fonction de sa position de 1, 2, 4, ...
Dans le manipse, il est similaire, mais au lieu de 1, 2, 3, 4, les bits ont la valeur 1/2, 1/4, 1/8, ... p> Donc si vous voulez représentent 0,75, les bits avec les valeurs 1/2 et 1/4 seraient définis dans votre maniçage et que l'exposant serait 0. C'est en très court.
Maintenant, si vous essayez de représenter une valeur de 0,11 dans une représentation à flotteur, vous remarquerez que cela n'est pas possible. Peu importe si vous utilisez Float32 ou Float64: P> (+/- mantisse) * 2 ^ Exponent code>.
La partie importante ici est la manipication, qui ne permet pas de représenter tous les chiffres exactement. La plage de valeurs de la manipication et l'exposant dépendent de la longueur de la longueur du flotteur que vous utilisez. L'exposant est responsable des chiffres représentables maximum et minimum, tandis que la Manjusse est responsable de la précision des numéros affichables (parlant de la "granularité" des chiffres). P> import numpy as np
item=np.float64('0.11')
print('{0:2.60f}'.format(item))
output: 0.110000000000000000555111512312578270211815834045410156250000
item=np.float32('0.11')
print('{0:2.60f}'.format(item))
output: 0.109999999403953552246093750000000000000000000000000000000000
Notez que le module décimal code> est idéal pour obtenir l'expansion décimale des flotteurs, par ex. impression (décimal.decimal (0.006)) code> ou avec un tableau numpy arr.sType (np.dtype (décimal)) code>
Merci pour le conseil. Je n'ai jamais utilisé cela. Mais si vous calculez avec des montants monétaires, c'est probablement une bonne alternative. Il pourrait également calculer avec la classe décimale Tge, mais il devrait ensuite utiliser décimal.decimal ('0.006') code> ranther que décimal.decimal (0.006) code>, car dans le dernier Case La valeur est transmise en tant que flotteur et les dommages sont déjà faits.
Sauf que les flotteurs python indigènes sont quelques ordres de magnitude plus rapidement que le module décimal, et NUMPY est encore plus rapide lorsque vous avez quelques milliers de valeurs à utiliser. Les formats de points flottants sont presque toujours la bonne chose à utiliser, ils peuvent simplement être un peu déroutant parfois!
La raison pour laquelle vous voyez deux résultats différents est que votre variable renvoie le résultat (précision inférieur) en 32 bits, tandis que p> premier multiplie avec Si vous spécifiez un autre type de "1", p> renvoie le même résultat que élément code> est dans Numpy.float32, comme vous l'avez dit. Python utilise à l'interne les nombres de points flottants 64 bits, de sorte que 1 code>, qui est un entier. Il n'est pas possible de multiplier entier avec flotteur, donc Python convertit à la fois en flotteurs - 64 bits flottants, car vous ne spécifiez rien d'autre. Le résultat est alors un flotteur 64 bits. P> Imprimer (article) code>, car il n'y a pas de conversion de type et tout peut rester en 32 bits. p> p>
Vous n'avez pas précisé exactement ce que le problème est, au-delà de "les chiffres ne correspondent pas". La manière dont vous gérez le point de flottement dépend un peu sur votre application, mais en général, vous ne pouvez pas compter sur la comparaison exactement des numéros de points flottants. Avec quelques exceptions évidentes: 0 fois que tout devrait être 0, 1 fois quelque chose devrait être 1 (il y en a plus, mais permet de les arrêter). Alors pourquoi est Droite, cela semble contredire le bon sens. Non, c'est juste dans le mauvais sens. Faites une comparaison effective et tout va toujours bien avec le monde. P> Les chiffres sont les mêmes. Cela devrait avoir du sens - augmenter la précision d'un point flottant ne doit pas modifier sa valeur et multiplier par Alors, qu'est-ce qui se passe? Numpy convertit un c'est donc ça. Quelles impressions Python ne sont pas censées être une représentation complètement précise des nombres. Les autres réponses entrent dans la raison pour laquelle EDIT strong>
L'arrondi ne change pas ceci, il convertit simplement 1 * élément code> différent de élément code>? 1 code> ne doit pas changer de numéro. P> np.float32 code> à un flotteur python qui imprime avec une belle arrondie. Cependant, item * 1 code> est un np.float64 code> qui par défaut montre plus de figures siginificantes. Si vous imprimez les deux avec la même quantité de chiffres significatifs, vous pouvez voir qu'il n'y a pas de différence réelle. P> 0,0006 code> ne peut pas être représenté exactement. P> article code> sur un flotteur python qui imprime avec arrondissement. P>
Bienvenue dans le monde merveilleux des arithmétiques de points flottants. Je ne pense pas que vous ressentez un problème, c'est à quel point le point flottant fonctionne. En effet, je reçois ces résultats exacts à ma fin
y-a-t-il un moyen d'éviter ça? Cela me fait des tas de problèmes sur la route.
Quel genre de problemes? Vous pouvez essayer de lire cette réponse à ce qui semble être un problème similaire, vous pouvez aussi essayez Ceci pour contourner les problèmes
@Jottbe Vous pouvez ajuster la précision imprimée b> avec np.set_printoptions
J'ai essayé d'ajuster les impressions, mais cela donne la même chose.
@gspr. Cette question concerne une conversion de type réelle, donc non
Quel est le dtype de
article * 1 code>? Il semble que cela soit élargi àfloat64 code>, qui est étrange, mais explicable. Quelle version de numpy utilisez-vous?@Nullman: Merci pour l'information, c'est pourquoi je n'ai pas vu les chiffres comme dans le poteau ci-dessus, mais bien sûr, l'erreur de précision est toujours présente et pourrait augmenter si la valeur est utilisée pour des calculs.
@gspr: Non, il n'est pas cassé, c'est un phénomène normal. Vous ne pouvez pas représenter des nombres arbitraires avec
float code>. Le système tente simplement d'utiliser la représentationfloat code> qui a la plus petite division de la valeur réelle et qui n'a généralement pas de mal.@Jottbe: Je suis bien conscient de cela. Par conséquent, je suis lié à la question canonique / réponse sur ce sujet. Le commentaire correspond à la manière dont le débordement de la pile affiche un tel avis de duplication possible.