Disparités d'arrondi à virgule flottante avec l'optimisation activée : un bug du compilateur ou un dilemme d'optimisation ?
Les calculs à virgule flottante peuvent souvent présenter un comportement inattendu, en particulier lorsque les optimisations du compilateur sont activées. Considérez l'extrait de code suivant :
#include <cstdlib> #include <iostream> #include <cmath> double round(double v, double digit) { double pow = std::pow(10.0, digit); double t = v * pow; double r = std::floor(t + 0.5); return r / pow; } int main() { std::cout << round(4.45, 1) << std::endl; std::cout << round(4.55, 1) << std::endl; }
Résultat attendu :
4.5 4.6
Cependant, lorsque ce code est compilé à l'aide de g avec des optimisations (O1 - O3), le résultat devient :
4.5 4.5
Cause de la disparité :
Ceci L'incohérence vient du fait que les processeurs x86 utilisent en interne une précision étendue de 80 bits pour les calculs en virgule flottante. Cependant, les variables doubles ont généralement une largeur de 64 bits. Lorsque les valeurs à virgule flottante sont stockées depuis les registres du processeur vers la mémoire, elles sont arrondies d'une précision de 80 bits à une précision de 64 bits. Cet arrondi peut introduire de légères erreurs.
Impact des niveaux d'optimisation :
Différents niveaux d'optimisation peuvent affecter la fréquence à laquelle les valeurs à virgule flottante sont enregistrées en mémoire. Avec des niveaux d’optimisation plus élevés, cela se produit plus fréquemment. En conséquence, l'erreur d'arrondi devient plus prononcée.
Solutions :
Considérations supplémentaires :
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!