3406 votes

Floating point math est cassé ?

<pre><code></code><p>Toutes les idées pourquoi cela se produit ?</p></pre>

2581voto

Brian R. Bondy Points 141769

Tous à virgule flottante de maths, c'est comme cela et est basé sur la norme IEEE 754. JavaScript utilise 64 bits à virgule flottante représentation, qui est le même que Java double.

Vous ne devriez jamais comparer avec == mais au lieu de comparer la valeur absolue de leur différence, et assurez-vous que cette différence est plus petite que la valeur Epsilon, qui est un très très petit nombre.

x = 0.2;
y = 0.3;
equal = (Math.abs(x - y) < 0.000001)

Pour la raison exacte, veuillez lire Ce que Chaque Ordinateur Scientifique Doit Savoir à Propos de l'Arithmétique à virgule Flottante. Pour une plus facile à digérer l'explication, voir floating-point-gui.de.

654voto

KernelPanik Points 1696

Un Concepteur de Matériel de point de vue

Je crois que je dois ajouter un matériel concepteur du point de vue de ce depuis que j'conception et la construction de matériel de point flottant. Connaître l'origine de l'erreur peut aider dans la compréhension de ce qui se passe dans le logiciel, et en fin de compte, j'espère que cela aide à expliquer les raisons pour lesquelles virgule flottante erreurs se produisent, et semblent s'accumuler au fil du temps.

1. Vue d'ensemble

D'un point de vue technique, la plupart des opérations en virgule flottante aura un certain élément d'erreur, puisque le matériel qui fait les calculs en virgule flottante est seulement nécessaire d'avoir une erreur de moins de la moitié d'une unité à la dernière place. Par conséquent, la quantité de matériel d'arrêt, une précision qui est nécessaire seulement pour le rendement d'une erreur de moins de la moitié d'une unité à la dernière place pour une seule opération, ce qui est particulièrement problématique en virgule flottante de la division. Ce qui constitue une seule opération dépend de combien d'opérandes l'unité. Pour la plupart, il en est deux, mais certaines unités en prendre 3 ou plusieurs opérandes. De ce fait, il n'ya aucune garantie que les opérations de entraînera une souhaitable d'erreur car les erreurs s'accumulent au fil du temps.

2. Normes

La plupart des processeurs de suivre la norme IEEE-754 la norme, mais une certaine utilisation anormale, ou des normes différentes . Par exemple, il y a un dénormalisée mode dans la norme IEEE-754, qui permet de représenter de très petits nombres à virgule flottante au détriment de la précision. La suite cependant, couvrira le mode normalisé de la norme IEEE-754, qui est le type de mode de fonctionnement.

Dans la norme IEEE-754, les concepteurs de matériel sont autorisés à la valeur de l'erreur/epsilon, tant que c'est moins de la moitié d'une unité à la dernière place, et le résultat doit être inférieur à la moitié d'une unité à la dernière place pour une seule opération. C'est ce qui explique pourquoi quand il y a des exécutions répétées, les erreurs s'accumulent. Pour la norme IEEE-754 double précision, c'est le 54e peu, depuis 53 bits sont utilisés pour représenter la partie numérique (normalisée), également appelé mantisse, du nombre à virgule flottante (par exemple, l'5.3 5.3e5). Les prochaines sections aller plus dans les détails sur les causes de l'erreur matérielle sur les différentes opérations en virgule flottante.

3. La Cause de l'Erreur d'Arrondi dans la Division

La principale cause de l'erreur de virgule flottante de la division sont la division des algorithmes utilisés pour calculer le quotient. La plupart des systèmes informatiques calculer la division à l'aide de la multiplication par l'inverse, principalement en Z=X/Y, Z = X * (1/Y). La Division est calculée de manière itérative, c'est à dire chaque cycle calcule certains bits du quotient jusqu'à ce que la précision souhaitée est atteinte, qui pour la norme IEEE-754 est quoi que ce soit avec une erreur de moins d'une unité à la dernière place. La table des inverses de Y (1/Y) est connu comme le quotient tableau de sélection (TVQ) en lente de la division, et la taille en bits du quotient tableau de sélection est généralement de la largeur de la base, ou le nombre de bits du quotient calculé à chaque itération, plus un peu de garde bits. Pour la norme IEEE 754 double précision (64-bit), il serait de la taille de la base de la cloison, plus un peu de garde bits k, où k>=2. Ainsi, par exemple, un type de Quotient Tableau de Sélection pour un diviseur qui calcule 2 bits du quotient à un moment (radix 4) serait de 2+2= 4 bits (plus quelques facultatif bits).

3.1 la Division de l'Erreur d'Arrondi: Rapprochement de la Réciproque

Ce inverses sont dans le quotient tableau de sélection dépendent de la méthode de répartition: la lenteur de la division tels que la théorie de la relativité restreinte d'une division ou division rapide comme Goldschmidt division; chaque entrée est modifiée en fonction de la répartition de l'algorithme dans une tentative de rendement le plus bas possible erreur. En tout cas, si, tous les inverses sont des approximations de la réelle réciproque, et d'introduire une certaine erreur. À la fois de ralentir la division et de la division rapide des méthodes de calculer le quotient de manière itérative, c'est à dire un certain nombre de bits du quotient sont calculées à chaque étape, le résultat est soustrait du dividende et le diviseur répète les étapes jusqu'à ce que l'erreur est de moins de la moitié d'une unité à la dernière place. Lent de la division des méthodes de calculer un nombre fixe de chiffres du quotient, à chaque étape, et sont généralement moins coûteux à construire, et la division rapide des méthodes de calculer un nombre variable de chiffres par étape et sont généralement plus coûteux à construire. La partie la plus importante de la division des méthodes est que la plupart d'entre eux reposent sur répétées de multiplication par un rapprochement de la réciprocité, de sorte qu'ils sont sujets à l'erreur.

4. Des Erreurs d'arrondi dans les Autres Opérations: la Troncature

Une autre cause des erreurs d'arrondi dans toutes les opérations sont les différents modes de la troncature de la réponse définitive que la norme IEEE-754 permet. Il y a tronquer, ronde-vers zéro, l' arrondi au plus proche (par défaut), ronde en bas, et le round-up. Toutes les méthodes d'introduire un élément d'erreur de moins de la moitié d'une unité à la dernière place pour une seule opération. Au fil du temps et des exécutions répétées, la troncature ajoute également de manière cumulative à l'erreur résultante. Cette erreur de troncation, est particulièrement problématique dans l'élévation à la puissance, ce qui implique une certaine forme de multiplication répétée.

5. Répété Les Opérations De

Étant donné que le matériel qui fait les calculs en virgule flottante ne doit produire un résultat avec une erreur de moins de la moitié d'une unité à la dernière place pour une seule opération, l'erreur va s'enrichir au fil des exécutions répétées si pas regardé. C'est la raison pour laquelle dans les calculs qui nécessitent une délimitée erreur, les mathématiciens utilisent des méthodes telles que l'utilisation de l'arrondi au plus proche même chiffre à la dernière place de la norme IEEE-754, car au fil du temps, les erreurs sont plus susceptibles d'annuler les uns les autres, et l'Arithmétique d'Intervalle, combiné avec les variations des modes d'arrondi IEEE 754 pour prédire les erreurs d'arrondi, et de les corriger. En raison de sa faible erreur relative par rapport à d'autres modes d'arrondi, rond le plus proche même les chiffres (en dernier lieu), est le mode d'arrondi par défaut de la norme IEEE-754.

Notez que le mode d'arrondi par défaut, arrondi au plus proche même les chiffres de la dernière place, garantit une erreur de moins de la moitié d'une unité à la dernière place pour une seule opération. En utilisant la troncature, le round-up, et arrondir seul peut en résulter une erreur qui est plus grande que la moitié d'une unité à la dernière place, mais de moins d'une unité à la dernière place, afin que ces modes ne sont pas recommandé, à moins qu'ils sont utilisés dans l'Arithmétique d'Intervalle.

6. Résumé

En bref, la raison fondamentale pour laquelle les erreurs dans les opérations à virgule flottante est une combinaison de la troncature dans le matériel et la troncature de la réciprocité dans le cas de la division. Depuis la norme IEEE-754 la norme exige seulement une erreur de moins de la moitié d'une unité à la dernière place pour une seule opération, le flottant point les erreurs de répétition, des opérations d'ajouter jusqu'à moins corrigé.

532voto

Joel Coehoorn Points 190579

Lorsque vous convertissez.1 ou 1/10 base 2 (binaire), vous obtenez un motif répété après la virgule, comme essayer de représenter 1/3 en base 10. La valeur n’est pas exacte, et donc vous ne peut pas exactement math avec elle à l’aide de méthodes normales de point flottant.

223voto

Devin Jeanpierre Points 23162

« « « Erreurs d’arrondi à virgule flottante. 0,1 ne peut être représentée aussi exactement en base 2 comme en base 10 à cause du facteur principal manquant de 5. Tout comme 1/3 prend un nombre infini de chiffres pour représenter sous forme décimale, mais est « 0.1 » à la base-3, 0,1 prend un nombre infini de chiffres en base 2 où elle ne fait pas dans la base 10. Et les ordinateurs n’ont pas une quantité infinie de mémoire.

132voto

Daniel Vassallo Points 142049

En plus des autres réponses correctes, vous pouvez envisager de mise à l'échelle de vos valeurs pour éviter les problèmes de l'arithmétique à virgule flottante.

Par exemple:

var result = 1.0 + 2.0;     // result === 3.0 returns true

... au lieu de:

var result = 0.1 + 0.2;     // result === 0.3 returns false

L'expression 0.1 + 0.2 === 0.3 retours false en JavaScript, mais heureusement entier de l'arithmétique en virgule flottante est exact, afin de représentation décimale des erreurs peuvent être évitées par la mise à l'échelle.

À titre d'exemple pratique, pour éviter à virgule flottante problèmes où la précision est primordiale, il est recommandé1 à manipuler de l'argent comme un entier représentant le nombre de cents: 2550 centimes au lieu de 25.50 de dollars.


1 Douglas Crockford: JavaScript: Les Bonnes Parties: Annexe A - Terrible Pièces (page 105).

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