Je veux tester les choses suivantes sur mon tableau cible:
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:
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:
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. 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. 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