Mathématiques entières avec pow() conduisant à des résultats incorrects
Considérez l'extrait de code suivant :
int i = 23; int j = 1; int base = 10; int k = 2; i += j * pow(base, k); cout << i << endl;
De façon attendue , ce code devrait afficher « 123 », mais à la place, il affiche étonnamment « 122 ». Ce résultat inattendu peut vous dérouter, surtout si vous compilez avec g 4.7.2 dans un environnement Windows XP.
Au cœur de cet écart se trouve le fait que std::pow() est conçu pour gérer nombres à virgule flottante. Bien que ces nombres à virgule flottante soient pratiques, ils ont un compromis : une précision limitée. Dans le cas de std::pow(), l'implémentation peut ne pas gérer l'exponentiation avec une précision parfaite, ce qui entraîne des erreurs d'arrondi.
Pour résoudre ce problème, on pourrait exploiter la puissance de C 11 et définir son propre nombre entier. fonction d'exponentiation :
constexpr int int_pow(int b, int e) { return (e == 0) ? 1 : b * int_pow(b, e - 1); }
Cette fonction int_pow personnalisée est spécialement conçue pour les entiers, garantissant ainsi une précision résultats.
Alternativement, une approche récursive de queue proposée par Dan Nissenbaum est également une solution viable :
constexpr int int_pow(int b, int e, int res = 1) { return (e == 0) ? res : int_pow(b, e - 1, b * res); }
Avec ces options à portée de main, vous pouvez désormais utiliser en toute confiance l'exponentiation entière dans votre C programmes, bannissant les résultats incorrects au royaume des bugs oubliés.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!