Risque d'opérations logiques sur des variables à virgule flottante en c ++

Erreurs d'arrondi en virgule flottante calcul peuvent créer des ravages avec des opérations logiques en C ++, vous devez donc être prudent effectuer des opérations logiques sur des variables à virgule flottante. Prenons l'exemple suivant:

flotter f1 = 10,0 flottant f2 = f1 / 3-bool b1 = (f1 == (f2 * 3.0)) - // sont ces deux égaux?

Même si il est évident pour nous que f1 est égal à f2 3 fois, la valeur résultante de b1 n'est pas nécessairement vrai. Une variable à virgule flottante ne peut pas contenir un nombre illimité de chiffres significatifs. Ainsi, f2 est pas égal au nombre que nous aimerions appeler “ trois et un tiers, n ° 148; mais plutôt à 3.3333 # 133-, arrêter après un certain nombre de décimales.

UN flotteur variable supporte les environ 7 chiffres de précision tout en un double soutient un skosh plus de 16 chiffres. Ces chiffres sont approximatifs car l'ordinateur est susceptible de générer un nombre comme 3,3333347 due aux aléas de calculs en virgule flottante.

Maintenant, en mathématiques pures, le nombre de 3s après la virgule est infini, mais pas d'ordinateur construit peut gérer un nombre infini de chiffres. Donc, après avoir multiplié par 3.3333 3, vous obtenez 9,9999 au lieu des 10 que vous obtiendriez si vous avez multiplié “ trois et un tiers ” - En effet, un erreur d'arrondi. Ces légères différences peuvent être imperceptible pour une personne, mais pas à l'ordinateur. L'égalité signifie exactement cela - exact l'égalité.

Les processeurs modernes sont sophistiqués pour effectuer ces calculs. Le processeur peut, en effet, accueillir l'erreur d'arrondi, mais de l'intérieur C ++, vous ne pouvez pas prédire exactement ce que tout processeur donné fera.




La comparaison sûre suit:

flotter f1 = 10,0 flottant f2 = f1 / 3-float f3 = f2 * 3.0 flottant delta = f1 - f3-bool = -0,0001 bEqual lt; delta delta lt; 0.0001-

Cette comparaison est vrai si f1 et f3 sont dans un petit delta de l'autre, ce qui devrait être encore vrai même si vous prenez une petite erreur d'arrondi en compte.

La logique ET et OU logique || opérateurs en C ++ effectuer ce qu'on appelle l'évaluation de court-circuit. Considérez ce qui suit:

condition1 condition2

Si condition1 n'est pas vrai, le résultat global est pas vrai, quelle que soit la valeur de condition2. (Par example, condition2 pourrait être vrai ou faux . sans changer le résultat) La même situation se produit dans ce qui suit:

condition1 || condition2

Si condition1 est vrai, le résultat est vrai, quelle que soit la valeur de condition2 est.

Pour gagner du temps, C ++ ne pas évaluer condition2 si elle n'a pas besoin de. Par exemple, dans l'expression condition1 condition2, C ++ ne pas évaluer condition2 si condition1 est fausse. De même, dans l'expression condition1 || condition2, C ++ ne pas évaluer condition2 si condition1 est vrai. Ceci est connu comme l'évaluation de court-circuit.

L'évaluation de court-circuit peut signifier que condition2 non exploité, même si cette condition a des effets secondaires. Considérez ce qui suit certes ménagé extrait de code:

int nArg1 = 1 int nArg2 = 2 int nArg3 = 3-bool b = (nArg1> nArg2) (nArg2 ++> nArg3) -

La variable nArg2 est jamais incrémenté puisque la comparaison nArg2 ++> nArg3 ne sont pas exécutées. Il n'y a pas besoin parce nArg1> nArg2 déjà retourné un faux si l'expression globale doit être fausse.


» » » » Risque d'opérations logiques sur des variables à virgule flottante en c ++