Question

Je suis tombé sur ce problème d'arithmétique suivante.

Mais le résultat est différent de l'opération mathématique normale, Pourquoi est-il?

double d1 = 1.000001;

double d2 = 0.000001;

Console.WriteLine((d1-d2)==1.0);
Était-ce utile?

La solution

Je suppose que vous avez trouvé la question sur la page Brainteasers Jon Skeet? Les réponses sont listées et expliquées sur le même site.

Pour une question de référence, voici la réponse copiée à partir de cette page.


3) arithmétique de Silly

Les ordinateurs sont destinés à être bon à l'arithmétique, sont-ils pas? Pourquoi cette impression « Faux »?

double d1 = 1.000001; double d2 =
0.000001; Console.WriteLine((d1-d2)==1.0);

Réponse: Toutes valeurs ici sont stockées sous forme binaire en virgule flottante. Bien que 1.0 peuvent être stockées exactement, 1,000001 est stockée comme 1,0000009999999999177333620536956004798412322998046875 et 0,000001 est stockée comme 0,000000999999999999999954748111825886258685613938723690807819366455078125. La différence entre eux est pas exactement 1,0, et en fait la différence ne peut pas être stocké exactement non plus.


Autres conseils

A partir de l'entrée MSDN pour Double.Equals :

  

Précision dans les comparaisons

     

La méthode Equals doit être utilisé avec   la prudence, parce que deux apparemment   des valeurs équivalentes peuvent être inégales en raison   à la précision différente des deux   valeurs. Les rapports exemple suivant   que la valeur double 0,3333 et la   Double retourné en divisant 1 par 3 sont   inégale.

     

...

     

Plutôt que de comparer l'égalité,   une technique recommandée implique   la définition d'une marge acceptable de   différence entre deux valeurs (telles que   0,01% de l'une des valeurs). Si la   La valeur absolue de la différence   entre les deux valeurs est inférieur ou   égale à cette marge, la différence   est susceptible d'être due à des différences de   précision et, par conséquent, les valeurs   sont susceptibles d'être égaux. Le suivant   exemple utilise cette technique pour comparer   .33333 et 1/3, les deux valeurs doubles   que l'exemple de code précédent trouvé   être inégale.

Si vous devez faire beaucoup de comparaisons « l'égalité », il pourrait être une bonne idée d'écrire une petite fonction d'aide ou méthode d'extension .NET 3.5 pour comparer:

public static bool AlmostEquals(this double double1, double double2, double precision)
{
    return (Math.Abs(double1 - double2) <= precision);
}

Cela pourrait être utilisé de la manière suivante:

double d1 = 1.000001;

double d2 = 0.000001;

bool equals = (d1 - d2).AlmostEquals(1.0, 0.0000001);

Voir cette question très similaire: C # .NET: Est-il sûr de vérifier les valeurs à virgule flottante pour l'égalité à 0

?

Il est parce que les ordinateurs font les mathématiques dans la base 2, et par conséquent beaucoup de nombres à virgule flottante décimaux ne peut pas être représenté exactement avec un nombre limité de chiffres.

Parce que vous utilisez des nombres à virgule flottante.

http://docs.sun.com/source/806-3568 /ncg_goldberg.html

Si vous faites cette arithmétique dans votre application, le decimal type doit être utilisé

decimal d1 = 1.000001M;

decimal d2 = 0.000001M;

Console.WriteLine((d1 - d2) == 1.0M); // evaluates as true

cela peut être dû à des problèmes de précision flottante de point, car il se pourrait que votre résultat est pas exactement 1.0 mais peut-être quelque chose comme 1,000000000001

Cela se produit parce que les types de virgule flottante enregistre des numéros en utilisant une base de deux et non une représentation de base dix. Ceci a pour conséquence que le double est incapable de stocker des valeurs telles que 0,1 exactement. Par exemple 0,1 est représentée par la valeur unique ,100000001490116119384765625.

Vous devez utiliser décimal pour se débarrasser de l'erreur.

Ceci est dû à la façon dont les nombres à virgule flottante travaillent dans le CPU, ce n'est pas C # spécifique. Voir cette entrée de Wikipedia et le papier ici pour plus d'informations.

La réponse courte est que les nombres à virgule flottante ne sont pas stockées sous la forme d'une représentation exacte, faisant une comparaison avec « == » ne fonctionne pas dans la façon dont vous essayez de l'utiliser.

Voyez ce que docs python doit Saym le problème est le même pour les deux:

http://docs.python.org/tutorial/floatingpoint.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top