Le problème de la calculatrice Google pourrait flotter contre.le double est-il une raison possible ?

StackOverflow https://stackoverflow.com/questions/27095

  •  09-06-2019
  •  | 
  •  

Question

J'ai fait ça juste pour le plaisir (donc, ce n'est pas vraiment une question, je vois déjà le downmodding se produire) mais, au lieu du nouveau logiciel de Google incapacité faire mathématiques correctement (vérifie ça!selon Google 500 000 000 000 002 - 500 000 000 000 001 = 0), j'ai pensé que j'essaierais ce qui suit en C pour exécuter un peu de théorie.

int main()
{
   char* a = "399999999999999";
   char* b = "399999999999998";

   float da = atof(a);
   float db = atof(b);

   printf("%s - %s = %f\n", a, b, da-db);

   a = "500000000000002";
   b = "500000000000001";
   da = atof(a);
   db = atof(b);
   printf("%s - %s = %f\n", a, b, da-db);
}

Lorsque vous exécutez ce programme, vous obtenez ce qui suit

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

Il semblerait que Google utilise une simple précision flottante de 32 bits (l'erreur ici), si vous remplacez float par double dans le code ci-dessus, vous résolvez le problème !Serait-ce ça ?

/mp

Était-ce utile?

La solution

en C#, essayez (double.maxvalue == (double.maxvalue - 100)) , vous obtiendrez true...

mais c'est ce que c'est censé être :

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

en y réfléchissant, vous avez 64 bits représentant un nombre supérieur à 2 ^ 64 (double.maxvalue), donc une inexactitude est attendue.

Autres conseils

Pour en savoir plus sur ce genre de bêtises, consultez cet article intéressant sur la calculatrice Windows.

Quand tu changes l'intérieur, personne ne le remarque

Les entrailles de calc - le moteur arithmétique - ont été complètement jetées et réécrites à partir de zéro.La bibliothèque de points flottants IEEE standard a été remplacée par une bibliothèque arithmétique de précision arbitraire.Cela a été fait après que les gens ont continué à écrire des articles HA-HA sur la façon dont Calc ne pouvait pas faire correctement l'arithmétique décimale, qui, par exemple, le calcul de 10,21 - 10.2 a entraîné 0,0100000000000016.

Il semblerait que Google utilise une simple précision flottante de 32 bits (l'erreur ici), si vous remplacez float par double dans le code ci-dessus, vous résolvez le problème !Serait-ce ça ?

Non, vous reportez simplement le problème.les doubles présentent toujours le même problème, mais avec des nombres plus grands.

@ebel

en y réfléchissant, vous avez 64 bits représentant un nombre supérieur à 2 ^ 64 (double.maxvalue), donc une inexactitude est attendue.

2^64 n'est pas la valeur maximale d'un double.2 ^ 64 est le nombre de valeurs uniques qu'un double (ou tout autre type 64 bits) peut contenir. Double.MaxValue est égal à 1,79769313486232e308.

L'inexactitude des nombres à virgule flottante ne vient pas du fait que les valeurs sont supérieures à Double.MaxValue (ce qui est impossible, sauf Double.PositiveInfinity).Cela vient du fait que la plage de valeurs souhaitée est tout simplement trop large pour correspondre au type de données.Nous abandonnons donc la précision en échange d’une portée efficace plus large.En substance, nous supprimons les chiffres significatifs en échange d’une plage d’exposants plus large.

@DrPizza

Pas même;les codages IEEE utilisent plusieurs codages pour les mêmes valeurs.Plus précisément, NaN est représenté par un exposant de tous les bits-1, puis par toute valeur non nulle pour la mantisse.Ainsi, il existe 252 NaN pour les doubles, 223 NaN pour les simples.

Vrai.Je n'ai pas tenu compte des encodages en double.Il y en a en fait 252-1 NaNs pour les doubles et 223-1 NaN pour les célibataires, cependant.:p

2^64 n'est pas la valeur maximale d'un double.2 ^ 64 est le nombre de valeurs uniques qu'un double (ou tout autre type 64 bits) peut contenir.Double.MaxValue est égal à 1.79769313486232e308.

Pas même;les codages IEEE utilisent plusieurs codages pour les mêmes valeurs.Plus précisément, NaN est représenté par un exposant de tous les bits-1, puis n'importe lequel valeur non nulle pour la mantisse.Il y a donc 252 NaN pour les doubles, 223 NaN pour les célibataires.

Vrai.Je n'ai pas tenu compte des encodages en double.Cependant, il existe en fait 252-1 NaN pour les doubles et 223-1 NaN pour les simples.:p

Doh, j'ai oublié de soustraire les infinis.

La version approximative de ce problème que j'ai apprise est que les flottants 32 bits vous donnent 5 chiffres de précision et que les flottants 64 bits vous donnent 15 chiffres de précision.Cela variera bien sûr en fonction de la façon dont les flottants sont codés, mais c'est un très bon point de départ.

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