Comment vérifier que la représentation à virgule flottante simple précision (32 bits) IEEE 754 est utilisée?

Je veux tester les choses suivantes sur mon tableau cible:

  • ‘Float’ est-il implémenté avec la variable à virgule flottante simple précision (32 bits) IEEE 754?
  • La «double» est-elle implémentée avec la variable à virgule flottante double précision (64 bits) IEEE 754?

Quels sont les moyens par lesquels je peux le tester avec un simple programme en C.

Aucun test simple n’existe.

La très grande majorité des systèmes actuels utilisent les formats IEEE-754 pour virgule flottante. Cependant, la plupart des implémentations C ne sont pas entièrement conformes à IEEE 754 (identique à CEI 60559) et ne définissent pas l’identificateur de préprocesseur __STDC_IEC_559__ . En l’absence de cet identifiant, le seul moyen de déterminer si une implémentation C est conforme à IEEE 754 consiste à utiliser un ou plusieurs des éléments suivants:

  • Lire sa documentation.
  • Examinez son code source.
  • Testez-le (ce qui est bien sûr difficile lorsque seuls des tests exhaustifs peuvent être concluants).

Dans de nombreuses implémentations et applications logicielles C, les écarts par rapport à IEEE 754 peuvent être ignorés ou contournés: vous pouvez écrire du code comme si vous utilisiez IEEE 754, et une grande partie du code fonctionnera en grande partie. Cependant, il y a une variété de choses qui peuvent tromper un programmeur sans méfiance; écrire du code à virgule flottante complètement correct est difficile même lorsque les spécifications complètes sont respectées.

Les écarts communs incluent:

  • L’arithmétique intermédiaire est effectuée avec plus de précision que le type nominal. Par exemple, les expressions qui utilisent double valeurs double peuvent être calculées avec long double précision long double .
  • sqrt ne renvoie pas une valeur correctement arrondie dans tous les cas.
  • D’autres routines de bibliothèques mathématiques renvoient des valeurs légèrement différentes (quelques ULP) des résultats correctement arrondis. (En fait, personne n’a mis en œuvre toutes les routines de calcul recommandées dans IEEE 754-2008 avec à la fois un arrondissement correct garanti et une durée d’exécution garantie.)
  • Les nombres inférieurs à la normale (des nombres minuscules près du bord du format à virgule flottante) peuvent être convertis en zéro au lieu d’être traités comme spécifié par IEEE 754.
  • Les conversions entre les nombres décimaux (par exemple, 3.1415926535897932384626433 dans le code source) et les formats binarys à virgule flottante (par exemple, le format double commun, binary IEEE-754 64 bits) ne sont pas toujours arrondies correctement, dans aucun sens de conversion.
  • Seul le mode arrondi au plus proche est pris en charge; les autres modes d’arrondi spécifiés dans IEEE 754 ne sont pas pris en charge. Ils peuvent aussi être disponibles pour des calculs simples mais requièrent l’utilisation d’un langage d’assemblage spécifique à la machine. Les bibliothèques mathématiques standard ( cos , log , etc.) prennent rarement en charge d’autres modes d’arrondi.

En C99, vous pouvez vérifier __STDC_IEC_559__ :

 #ifdef __STDC_IEC_559__ /* using IEEE-754 */ #endif 

Cela est dû au fait que la norme internationale à virgule flottante référencée par C99 est IEC 60559: 989 (IEC 559 et IEEE-754 étaient une description précédente). Le mappage du langage C à la norme CEI 60559 est facultatif, mais s’il est utilisé, l’implémentation définit la macro __STDC_IEC_559__ (annexe F de la norme C99). Vous pouvez donc vous y fier totalement.

Une autre solution consiste à vérifier manuellement si les valeurs dans float.h , telles que FLT_MAX , FLT_EPSILON , FLT_MAX_10_EXP , etc., correspondent aux limites IEEE-754, bien que théoriquement, une autre représentation avec les mêmes valeurs puisse exister.

Tout d’abord, vous trouverez des informations détaillées sur l’ISO / CEI / IEEE 60559 (ou IEEE 754) dans Wikipedia:

Types standard à virgule flottante

Comme F. Goncalvez vous l’a dit, la macro __STDC_IEC_559__ vous apporte des informations sur votre compilateur, qu’il soit conforme à la norme IEEE 754 ou non.

Dans ce qui suit, nous

Toutefois, vous pouvez obtenir des informations supplémentaires avec la macro FLT_EVAL_METHOD .

La valeur de cette macro signifie:

  • 0 Toutes les opérations et les constantes sont évaluées dans la plage et la précision du type utilisé.

  • 1 Les opérations des types float et double sont évaluées dans la plage et la précision de double , et long double va à votre manière …

  • 2 Les évaluations de tous types sont effectuées dans la précision et la plage de long double .

  • -1 indéterminé

  • Autres valeurs négatives: Implémentation définie (cela dépend de votre compilateur).

Par exemple, si FLT_EVAL_METHOD == 2 et que vous conservez le résultat de plusieurs calculs dans une variable à virgule flottante x , toutes les opérations et les constantes sont calculées ou traitées dans la meilleure précision, c’est-à-dire long double , mais seul le résultat final est arrondi au type que x a.

Ce comportement réduit l’impact des erreurs numériques.

Pour connaître les détails des types à virgule flottante, vous devez surveiller les macros constantes fournies par l’en-tête standard .
Par exemple, voir ce lien:

Caractéristiques des types à virgule flottante


Au cas où votre implémentation ne serait pas conforme à la norme IEEE 754, vous pouvez essayer de rechercher des détails dans l’en-tête standard , s’il existe.
De plus, vous devez lire la documentation de votre compilateur.

Par exemple, le compilateur GCC explique ce que fait la virgule flottante:

Stadus of C99 dans GCC