HOWTO · C

Imprimer les nombres en notation scientifique en C

Cet article présente comment imprimer des nombres en notation scientifique en C

Sur cette page

Utilisez la conversion %e ou %E dans printf pour afficher une valeur à virgule flottante en notation scientifique. La conversion en minuscule affiche un marqueur d’exposant en minuscule ; celle en majuscule affiche un marqueur en majuscule. Une précision telle que %.3e définit le nombre de chiffres après la virgule dans la significande.

Exécutez cet exemple :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

#include <stdio.h>

int main(void) {
    double values[] = {123456.789, -0.000012345};

    printf("lowercase: %.3e\n", values[0]);
    printf("uppercase: %.3E\n", values[1]);
    return 0;
}

Fonctionnement de la notation scientifique en C

La notation scientifique exprime une valeur non nulle comme le produit d’une significande par une puissance de dix. La significande comporte un seul chiffre non nul avant la virgule ; l’exposant indique de combien de rangs la virgule se déplace. Par exemple, 123456 peut s’écrire 1.23456 × 10^5, tandis que 0.0000123 peut s’écrire 1.23 × 10^-5.

Cette notation change la façon d’afficher une valeur, pas la façon dont le type float ou double sous-jacent la stocke. Les types à virgule flottante binaires ont une précision limitée : de nombreuses fractions décimales ne sont donc stockées qu’approximativement. Afficher davantage de chiffres peut révéler plus précisément cette approximation stockée, mais n’augmente pas la précision de la valeur en mémoire.

Afficher la notation scientifique avec printf

Les conversions e et E formatent un argument de type double en notation scientifique. La casse du marqueur d’exposant dépend de la conversion : %e utilise e et %E utilise E. L’exposant comporte un signe, et les implémentations affichent suffisamment de chiffres pour le représenter. Utilisez %f si vous souhaitez comparer avec une notation à virgule fixe. La spécification POSIX de fprintf définit les conversions e et E, ainsi que leur comportement en matière de précision.

Dans l’exemple d’introduction, %.3e et %.3E affichent chacun trois chiffres après la virgule dans la significande. Le signe de la valeur reste présent dans le nombre formaté. Pour les valeurs dont l’affichage en notation à virgule fixe serait difficile à lire, la notation scientifique garde une significande compacte et l’exposant indique l’ordre de grandeur.

La conversion attend un argument de type double. Un float transmis à printf est promu en double, contrairement à un entier. Pour formater un entier en notation scientifique, convertissez-le explicitement, par exemple avec (double)count, puis utilisez %e ou %E. La conversion en double peut faire perdre des chiffres de faible poids aux grands entiers qui dépassent la précision représentable par ce type.

Régler le nombre de chiffres après la virgule

Pour %e et %E, la précision compte les chiffres après la virgule, et non le nombre total de chiffres significatifs. Ainsi, %.2e affiche deux chiffres fractionnaires dans la significande, soit généralement trois chiffres significatifs au total. Si vous ne précisez pas la précision, la valeur par défaut est de six chiffres après la virgule. La valeur est arrondie pour l’affichage à la précision demandée ; sa valeur stockée ne change pas. La spécification POSIX de fprintf précise cette règle et la valeur par défaut de six chiffres.

Choisissez la précision adaptée au format d’affichage ou d’échange dont votre application a besoin. Afficher davantage de chiffres ne garantit pas que la chaîne décimale représente exactement la valeur à virgule flottante binaire. Si vous avez besoin d’un nombre précis de chiffres significatifs, tenez compte du chiffre initial de la significande lorsque vous choisissez la précision.

Formater des chaînes en notation scientifique sans risque

Lorsque vous devez stocker le nombre formaté ou le transmettre à une autre fonction, utilisez snprintf en indiquant la capacité du tampon. Cette capacité inclut le caractère nul de fin. La fonction renvoie le nombre de caractères qui auraient été écrits, sans compter ce caractère ; une valeur de retour supérieure ou égale à la capacité signifie que la sortie a été tronquée. Une valeur de retour négative indique une erreur de formatage. La spécification POSIX de fprintf définit la valeur de retour de snprintf et son comportement en cas de troncation.

Exécutez cet exemple autonome :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

#include <stdio.h>

int main(void) {
    double measurement = 0.000012345;
    char text[64];
    int length = snprintf(text, sizeof text, "%.3e", measurement);

    if (length < 0) {
        puts("formatting error");
        return 1;
    }
    if ((size_t)length >= sizeof text) {
        puts("buffer too small");
        return 1;
    }

    printf("value: %s\n", text);
    return 0;
}

snprintf écrit au plus autant de caractères que la capacité disponible le permet et termine le tampon par un caractère nul si sa capacité est supérieure à zéro. Vérifiez sa valeur de retour avant de considérer le tampon comme un résultat formaté complet. Évitez sprintf, qui ne limite pas l’écriture, lorsque vous ne pouvez pas garantir que le tampon sera assez grand.

Faut-il écrire une fonction personnalisée de notation scientifique ?

En général, non. Selon les règles de formatage de la bibliothèque C, %e et %E gèrent déjà la significande, l’exposant, le signe, l’arrondi et la valeur zéro. Une conversion écrite à la main doit traiter zéro séparément et normaliser aussi bien les valeurs inférieures à un que celles supérieures ou égales à dix. Elle doit également tenir compte des valeurs négatives, des arrondis qui modifient la significande et des limites du type numérique. Une boucle qui ne fait que diviser des valeurs positives par dix ne couvre pas correctement ces cas.

Préférez printf pour l’affichage direct et snprintf pour produire une chaîne dans un tampon de taille limitée. N’écrivez un formateur personnalisé que si vous avez besoin d’une représentation précise que les conversions standard ne peuvent pas fournir ; définissez-en le comportement pour toute la plage d’entrée et vérifiez-le. Pour la notation scientifique ordinaire, les conversions standard sont plus courtes et moins sujettes aux erreurs.