Maison > développement back-end > C++ > Pourquoi l'arithmétique à virgule flottante produit-elle des résultats différents entre les architectures x86 et x64 ?

Pourquoi l'arithmétique à virgule flottante produit-elle des résultats différents entre les architectures x86 et x64 ?

Barbara Streisand
Libérer: 2024-11-03 03:12:29
original
1014 Les gens l'ont consulté

Why does floating-point arithmetic produce different results between x86 and x64 architectures?

Différences dans l'arithmétique à virgule flottante : x86 contre x64

Dans un extrait de code impliquant l'arithmétique à virgule flottante, des incohérences surviennent entre MS VS Builds 2010 ciblant les architectures x86 et x64. Le code est le suivant :

float a = 50.0f;
float b = 65.0f;
float c =  1.3f;
float d = a*c;
bool bLarger1 = d < b;
bool bLarger2 = (a*c) < b;
Copier après la connexion

Écarts :

  • Construction x86 : La variable bLarger1 est fausse (d et b sont définis sur 65,0), tandis que bLarger2 est vrai.
  • Construction x64 : bLarger1 et bLarger2 sont faux.

Problème sous-jacent :

L'écart provient de l'expression bool bLarger2 = (a*c) < b;. Bien que cela semble représenter la même comparaison que bool bLarger1 = d < b, il effectue en fait la multiplication et la comparaison séparément.

Différence entre les unités à virgule flottante :

La principale différence réside dans les unités à virgule flottante utilisées par les deux architectures. L'architecture x86 utilise l'unité à virgule flottante x87, qui effectue des calculs avec une précision supérieure à la simple précision (généralement en double précision). En revanche, l'architecture x64 utilise l'unité à virgule flottante SSE, qui effectue des calculs purs en simple précision.

Impact sur la multiplication :

Dans l'expression bLarger1, la multiplication de a et c est effectuée par l'instruction de multiplication matérielle. Cette instruction utilise une précision en double précision, ce qui fait que d est défini sur 65,0.

Cependant, dans l'expression bLarger2, la multiplication est explicitement effectuée en simple précision en raison de la conversion de type (a*c). Cela a pour résultat que (a*c) est réglé sur 64,999992.

Contrôle de précision x87 :

Par défaut, l'unité x87 fonctionne en double précision. Cependant, il est possible de persuader l'unité d'effectuer des calculs en simple précision à l'aide de la fonction _controlfp.

_controlfp(_PC_24, _MCW_PC);
Copier après la connexion

En ajoutant cette ligne au code 32 bits, bLarger1 et bLarger2 seront définis sur false.

Options du compilateur :

Dans les versions plus récentes de Visual Studio, le compilateur peut émettre des instructions SSE même pour les cibles 32 bits. Cela garantit la cohérence de l'arithmétique à virgule flottante dans différentes architectures.

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal