6 votes

Le bug du calculateur Google, est-ce que le passage de float à double pourrait être une raison possible ?

Avec la nouvelle incapacité de Google à faire des mathématiques correctement (vérifiez-le! selon Google 500,000,000,000,002 - 500,000,000,000,001 = 0), j'ai pensé essayer ce qui suit en C pour tester une petite 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 sur 32 bits (l'erreur ici), si vous remplacez float par double dans le code ci-dessus, vous résolvez le problème! Est-ce que cela pourrait être la solution?

4voto

Frank Krueger Points 27508

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

Lorsque vous changez 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 standard flottante IEEE a été remplacée par une bibliothèque arithmétique à précision arbitraire. Cela a été fait après que les gens ont continué à écrire des articles moqueurs sur le fait que Calc ne pouvait pas effectuer correctement l'arithmétique décimale, que par exemple, calculer 10,21 - 10,2 donnait 0,0100000000000016.

2voto

DrPizza Points 9355

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 corrigez le problème ! Est-ce que cela pourrait être ça ?

Non, vous ne faites que différer le problème. Les doubles présentent toujours le même problème, mais avec des nombres plus grands.

2voto

gil Points 828

En C#, essayez (double.maxvalue == (double.maxvalue - 100)), vous obtiendrez true mais c'est ce qui est censé arriver.

En y réfléchissant, vous avez 64 bits représentant un nombre supérieur à 2^64 (double.maxvalue), donc l'approximation est attendue.

1voto

Derek Park Points 25025

@ebel

en y réfléchissant, vous avez 64 bits représentant un nombre supérieur à 2^64 (double.maxvalue), donc l'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 sur 64 bits) peut contenir. Double.MaxValue est égal à 1.79769313486232e308.

L'inexactitude avec les nombres à virgule flottante ne vient pas de la représentation de valeurs plus grandes que Double.MaxValue (ce qui est impossible, à l'exception de Double.PositiveInfinity). Elle vient du fait que la plage de valeurs désirée est simplement trop grande pour tenir dans le type de données. Ainsi, nous abandonnons la précision en échange d'une plage effective plus large. En substance, nous abandonnons des chiffres significatifs en échange d'une plus grande plage d'exposants.

@DrPizza

Même pas; les codages IEEE utilisent de multiples codages pour les mêmes valeurs. Spécifiquement, NaN est représenté par un exposant de tous les bits à 1, puis toute valeur non nulle pour la mantisse. Ainsi, il y a 252 NaN pour les doubles, 223 NaN pour les float.

Vrai. Je n'ai pas tenu compte des encodages en double. En réalité, il y a en fait 252-1 NaN pour les doubles et 223-1 NaN pour les float, cependant. :p

0voto

DrPizza Points 9355

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.

Même pas; les encodages IEEE utilisent des encodages multiples pour les mêmes valeurs. Plus précisément, NaN est représenté par un exposant de tous les bits à 1, puis n'importe quelle valeur non nulle pour la mantisse. Ainsi, il existe 252 NaN pour les doubles, 223 NaN pour les floatants.

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