Do-s and Don’t-s pour l’arithmétique en virgule flottante?

Quelles sont les bonnes choses à faire et à ne pas faire en arithmétique en virgule flottante (IEEE754 en cas de confusion) pour assurer une bonne stabilité numérique et une grande précision des résultats?

Je sais que certains, par exemple, ne soustraient pas des quantités de magnitude similaire, mais je suis curieux de savoir quelles autres bonnes règles existent.

Tout d’abord, entrez dans l’idée que les nombres en virgule flottante NE suivent PAS nécessairement les mêmes règles que les nombres réels … une fois que vous avez accepté cela, vous comprendrez la plupart des pièges.

Voici quelques règles / conseils que j’ai toujours suivis:

  • NE JAMAIS comparer un nombre à virgule flottante à zéro ou à quoi que ce soit d’autre (IE ne le fait pas: if (myFloat == 0)
  • La propriété associative ne tient pas pour la virgule flottante … sens (a + b) + c != a + (b + c)
  • Rappelez-vous qu’il y a toujours des arrondis
  • Les nombres à virgule flottante n’ont pas nécessairement d’inverse unique
  • Pas de fermeture avec des nombres à virgule flottante … Ne supposez jamais que le résultat d’une opération à virgule flottante donne un nombre à virgule flottante valide.
  • La propriété dissortingbutive ne tient pas
  • Essayez d’éviter d’utiliser des comparaisons en virgule flottante … car une erreur d’arrondi peut provoquer des résultats inattendus

La règle n ° 1 “ne pas” avec les nombres à virgule flottante est:

N’utilisez pas de nombres à virgule flottante où les entiers suffiront.

Comprenez comment se comporte la virgule flottante.

NE croyez PAS que de simples règles suffiront pour les utiliser correctement.

Par exemple, au moins deux réponses ont proposé d’interdire la comparaison de la virgule flottante à l’égalité. Il existe d’abord des cas où il est nécessaire de les comparer pour obtenir l’égalité. Ensuite, lorsque vous avez besoin de vérifier la distance, vous devez également être conscient du fait que le piège est son piège. Par exemple, il n’est pas transitif, propriété que la plupart des gens assumeront comme test d’égalité.

N’oubliez pas qu’en raison d’une arithmétique en virgule flottante défectueuse, des personnes sont mortes et des milliards de dollars de dommages sont survenus.

ne jamais essayer de faire une comparaison d’égal à égal

double da, db;

si (da == db) alors quelque chose.

rappelez-vous que C utilise le double par défaut, donc si vous voulez faire une simple précision, soyez clair à ce sujet

float fa, fb;

fa = fb + 1,0;

va convertir fb en double faire un double append puis convertir en simple et faire un seul égal

Au lieu

fa = fb + 1,0F.

tous célibataires.

Si vous comptez utiliser un nombre entier tel que 1.0, n’en faites pas une décimale dans votre code. vous obtenez plus de fiabilité de vos compilateurs / outils si vous pouvez minimiser les nombres ASCII. alors

fa = fb + 1;

ou au lieu de

fa = fb + 0,3333333F;

faites quelque chose comme ça (si vous êtes intéressé par la précision).

fc = 1; fc = fc / 3; fa = fb + fc;

Beaucoup, beaucoup de choses, la virgule flottante est douloureuse, les compilateurs et les bibliothèques ne sont pas très bons, les fpus ont des bogues et l’IEEE est exceptionnellement douloureux et conduit à plus de bogues. Malheureusement, c’est le monde dans lequel nous vivons sur la plupart des plateformes.

Mon “arme principale” pour éviter les pièges en virgule flottante consiste à bien comprendre leur façon de travailler. Je pense que Chris Hecker explique assez bien les bases.

Recherchez, téléchargez et lisez “ce que tout informaticien devrait savoir sur l’arithmétique en virgule flottante”