Voici quelques programmes C pour tester l'arithmétique flottante de votre machine:
Divers tests de l'arithmétique flottante: test de l'évaluation des expressions flottantes en C (montrant un bug dans gcc lorsque le processeur est configuré en précision étendue, par exemple sous Linux/x86), test de l'addition et de la multiplication avec des zéros signés, test de la fonction puissance pow
. Les résultats sur diverses machines (archive compressée) et un résumé partiel (fichier texte).
Test des fonctions d'arrondi à l'entier le plus proche, dans les quatre modes d'arrondi IEEE 754: cast en type int, trunc
, floor
, ceil
, round
, nearbyint
, rint
. Ces tests montrent un bug de l'implémentation de la fonction rint
dans la glibc sur PowerPC (corrigé dans le CVS le 6 janvier 2005).
Test de la fonction arc tangente atan
(voir le bug Debian 210613).
Test de la fonction logarithme log
(voir le bug Debian 210400).
Test de la fonction sinus sin
.
Test du comportement de l'overflow avec gcc et une précision étendue intermédiaire (par exemple, sous Linux/x86).
Test des fonctions gamma tgamma
, lgamma
et lgamma_r
.
Test de la fonction remquo
.
Test de la fonction fma
(voir le bug 3268 de la glibc et le bug Debian 372544).
Test de l'effet de la contraction en FMA en calculant sqrt (a * a - b * b)
avec a = b (le code est écrit de telle manière que cette égalité ne devrait pas être utilisée pour optimiser au moment de la compilation). La norme ISO C99 autorise, sous certaines conditions, la contraction d'expressions flottantes: par exemple, l'expression x * y + z
peut être contractée en une seule opération (avec un seul arrondi) sur les processeurs qui ont un FMA. En général, cela améliore la précision des calculs, mais cela peut aussi avoir l'effet inverse, voire produire des effets secondaires, comme dans le code ci-dessus, où la symétrie est cassée par l'introduction d'un FMA. C'est pour cela que la contraction d'expressions flottantes peut être désactivée par le pragma FP_CONTRACT; dans ce cas, le résultat de ce programme devrait toujours être 0. Mais GCC jusqu'à 4.8 ignore le pragma FP_CONTRACT mis à OFF, si bien que le programme donne des résultats incorrects sur les processeurs PowerPC, IA-64 (Itanium), et les x86_64 récents. Pire, même dans le cas général (non trivial et éventuellement utile en pratique) a >= b ? sqrt (a * a - b * b) : 0
, on peut obtenir un NaN.
Par exemple, en faisant tourner contract2fma (compilé avec GCC 4.8 ou inférieur sur l'une des architectures mentionnées ci-dessus) sur 1, 1.1 et 1.2, on obtient:
Test of a >= b ? sqrt (a * a - b * b) : 0 with FP_CONTRACT OFF test(1) = 0 test(1.1000000000000000888) = 2.9802322387695326562e-09 test(1.1999999999999999556) = nan
Note: Avec GCC 4.9 et plus récent, on doit compiler en mode ISO C (-std=c99 ou -std=c11) pour que la contraction d'expressions flottantes soit désactivée par défaut (nécessaire puisque GCC ignore toujours le pragma FP_CONTRACT).
Mesure la performance de fegetround
/fesetround
quand le mode d'arrondi ne change pas. Voir la discussion glibc very old, et en particulier ce message.
Teste diverses expressions simples pouvant mener à des transformations par le compilateur dans le but d'optimiser. De telles transformations sont valides sur les nombres réels, mais peuvent ici être invalides à cause des valeurs spéciales IEEE 754 (NaN, infinis, zéros signés).
Les résultats peuvent être affectés par les options de compilation liées aux optimisations d'expressions en virgule flottante. Voir un exemple d'utilisation avec GCC (détails au sujet de la virgule flottante avec GCC). Dans les erreurs, y0 est la valeur obtenue et y1 est la valeur attendue (correcte). Note: on suppose que le qualificateur volatile
a pour effet de désactiver les optimisations, sinon rien n'est testé (voir le source).
Ce fichier C est en fait généré à partir de transformations.c avec le script Perl gen-transf.