Maison > développement back-end > C++ > le corps du texte

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
870 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!

source:php.cn
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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!