matherr(3)

NOM
matherr — Gestionnaire d'exception SVID de la bibliothèque mathématique

BIBLIOTHÈQUE
Bibliothèque de math (libm, -lm)

SYNOPSIS
#include <math.h>

[[obsolète]] int matherr(struct exception *exc);

[[obsolète]] extern _LIB_VERSION_TYPE _LIB_VERSION;

DESCRIPTION
Note : Le mécanisme décrit dans cette page n'est plus pris en charge par la glibc. Avant la glibc 2.27, il a été marqué comme obsolète. Depuis la glibc 2.27, il a été complètement supprimé. Les nouvelles applications devraient utiliser les techniques décrites dans math_error(7) et fenv(3). Cette page documente le mécanisme matherr() de la glibc comme aide pour maintenir et porter d'anciennes applications.

La spécification « System V Interface Definition » (SVID) spécifie que différentes fonctions mathématiques devraient appeler une fonction matherr() en cas d'exception mathématique. Cette fonction est appelée avant que la fonction mathématique ne rende la main ; après le retour de matherr(), le système retourne dans la fonction mathématique qui renvoie le résultat à l'appelant.

Pour utiliser matherr(), le programmeur doit définir la macro de test de fonctionnalité _SVID_SOURCE (avant d'inclure tout fichier d'en-tête) et définir la variable externe _LIB_VERSION à la valeur _SVID_.

Le système fournit une version par défaut de matherr(). Cette version ne fait rien et renvoie zéro (voir ci-dessous pour la signification). La fonction matherr() par défaut peut être remplacée par une version spécifique au programme qui sera appelée quand une exception se produit. La fonction est appelée avec un paramètre, un pointeur vers une structure exception, défini comme ceci :

    struct exception {
        int    type;      /* Type d'exception */
        char  *name;      /* Nom de la fonction ayant
                             produit l'exception */
        double arg1;      /* 1er paramètre de la fonction */
        double arg2;      /* 2ème paramètre de la fonction */
        double retval;    /* Valeur renvoyée par la fonction */
    }

Le champ type peut prendre une des valeurs suivantes :

DOMAIN
    Une erreur de domaine s'est produite (un paramètre de la fonction était en dehors du domaine de définition de la fonction). La valeur renvoyée dépend de la fonction ; errno prend la valeur EDOM.

SING
    Une erreur de pôle s'est produite (le résultat de la fonction est un infini). La valeur renvoyée dans la plupart des cas est HUGE (le plus grand nombre en virgule flottante simple précision), avec le bon signe. Dans la plupart des cas, errno prend la valeur EDOM.

OVERFLOW
    Un dépassement s'est produit. Dans la plupart des cas, la valeur HUGE est renvoyée et errno prend la valeur ERANGE.

UNDERFLOW
    Un soupassement (« underflow ») s'est produit. 0.0 est renvoyé et errno prend la valeur ERANGE.

TLOSS
    Perte complète de chiffres significatifs. 0,0 est renvoyé et errno prend la valeur ERANGE.

PLOSS
    Perte partielle de chiffres significatifs. La valeur n'est pas utilisée par la glibc (et beaucoup d'autres systèmes).

Les champs arg1 et arg2 sont les paramètres fournis à la fonction (arg2 n'est pas défini pour les fonctions qui ne prennent qu'un seul paramètre).

Le champ retval spécifie la valeur que la fonction mathématique va renvoyer à l'appelant. La fonction matherr() définie par le programmeur peut modifier ce champ pour changer la valeur renvoyée par la fonction mathématique.

Si la fonction matherr() renvoie zéro, alors le système positionne errno comme décrit ci-dessus et peut afficher un message d'erreur sur la sortie d'erreur standard (voir ci-dessous).

Si la fonction matherr() renvoie une valeur non nulle, alors le système ne positionne pas errno et n'affiche pas de message d'erreur.

  Fonctions mathématiques qui utilisent matherr()
La table ci-dessous liste les fonctions et les circonstances pour lesquelles matherr() est appelée. La colonne « Type » indique la valeur donnée à exc->type lors de l'appel à matherr(). La colonne « Résultat » est la valeur du résultat par défaut donnée à exc->retval.

Les colonnes « Msg? » et « errno » décrivent le comportement par défaut si matherr() renvoie zéro. Si la colonne « Msg? » contient « o », alors le système affiche un message d'erreur sur la sortie d'erreur standard.

La table utilise les notations et abréviations suivantes :

    x premier paramètre de la fonction
    y second paramètre de la fonction
    fin valeur finie du paramètre
    neg valeur négative du paramètre
    int valeur entière du paramètre
    o/f dépassement du résultat
    u/f soupassement du résultat
    |x| valeur absolue de x
    X_TLOSS est une constante définie dans <math.h>
Fonction | Type | Résultat | Msg ? | errno
acos(|x|>1) | DOMAIN | HUGE | y | EDOM
asin(|x|>1) | DOMAIN | HUGE | y | EDOM
atan2(0,0) | DOMAIN | HUGE | y | EDOM
acosh(x<1) | DOMAIN | NAN | y | EDOM |
atanh(|x|>1) | DOMAIN | NAN | y | EDOM |
atanh(|x|==1) | SING | (x>0.0)? | y | EDOM |
 |  | HUGE_VAL :
 |  | -HUGE_VAL
cosh(fin) o/f | OVERFLOW | HUGE | n | ERANGE
sinh(fin) o/f | OVERFLOW | (x>0.0) ? | n | ERANGE
 |  | HUGE : -HUGE
sqrt(x<0) | DOMAIN | 0.0 | y | EDOM
hypot(fin,fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp(fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp(fin) u/f | UNDERFLOW | 0.0 | n | ERANGE
exp2(fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp2(fin) u/f | UNDERFLOW | 0.0 | n | ERANGE
exp10(fin) o/f | OVERFLOW | HUGE | n | ERANGE
exp10(fin) u/f | UNDERFLOW | 0.0 | n | ERANGE
j0(|x|>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
j1(|x|>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
jn(|x|>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
y0(x>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
y1(x>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
yn(x>X_TLOSS) | TLOSS | 0.0 | y | ERANGE
y0(0) | DOMAIN | -HUGE | y | EDOM
y0(x<0) | DOMAIN | -HUGE | y | EDOM
y1(0) | DOMAIN | -HUGE | y | EDOM
y1(x<0) | DOMAIN | -HUGE | y | EDOM
yn(n,0) | DOMAIN | -HUGE | y | EDOM
yn(x<0) | DOMAIN | -HUGE | y | EDOM
lgamma(fin) o/f | OVERFLOW | HUGE | n | ERANGE
lgamma(-int) ou | SING | HUGE | y | EDOM
lgamma(0)
tgamma(fin) o/f | OVERFLOW | HUGE_VAL | n | ERANGE
tgamma(-int) | SING | NAN | y | EDOM
tgamma(0) | SING | copysign( | y | ERANGE
 |  | HUGE_VAL,x)
log(0) | SING | -HUGE | y | EDOM
log(x<0) | DOMAIN | -HUGE | y | EDOM
log2(0) | SING | -HUGE | n | EDOM |
log2(x<0) | DOMAIN | -HUGE | n | EDOM |
log10(0) | SING | -HUGE | y | EDOM
log10(x<0) | DOMAIN | -HUGE | y | EDOM
pow(0.0,0.0) | DOMAIN | 0.0 | y | EDOM
pow(x,y) o/f | OVERFLOW | HUGE | n | ERANGE
pow(x,y) u/f | UNDERFLOW | 0.0 | n | ERANGE
pow(NaN,0.0) | DOMAIN | x | n | EDOM
0**neg | DOMAIN | 0.0 | y | EDOM |
neg**non-int | DOMAIN | 0.0 | y | EDOM
scalb() o/f | OVERFLOW | (x>0.0) ? | n | ERANGE
 |  | HUGE_VAL :
 |  | -HUGE_VAL
scalb() u/f | UNDERFLOW | copysign( | n | ERANGE
 |  | 0.0,x)
fmod(x,0) | DOMAIN | x | y | EDOM
remainder(x,0) | DOMAIN | NAN | y | EDOM |

ATTRIBUTS
Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface | Attribut | Valeur
matherr() | Sécurité des threads | MT-Safe

EXEMPLES
Le programme d'exemple montre l'utilisation de matherr() lors de l'appel à log(3). Le programme prend jusqu'à 3 paramètres en ligne de commande. Le premier paramètre est le nombre en virgule flottante à fournir à log(3). Si le deuxième paramètre, optionnel, est fourni, _LIB_VERSION est configuré à la valeur _SVID_ de telle sorte que matherr() soit appelée et l'entier fourni sur la ligne de commande est utilisé comme valeur renvoyée par matherr(). Si le troisième paramètre, optionnel, est fourni, il spécifie une autre valeur que matherr() doit positionner comme valeur renvoyée de la fonction mathématique.

L'exécution suivante de l'exemple (dans laquelle log(3) reçoit la valeur 0.0) n'utilise pas matherr() :

    $ ./a.out 0.0
    errno: Numerical result out of range
    x=-inf

Dans l'exécution suivante, matherr() est appelée et renvoie 0 :

    $ ./a.out 0.0 0
    matherr SING exception in log() function
            args:   0.000000, 0.000000
            retval: -340282346638528859811704183484516925440.000000
    log: SING error
    errno: Numerical argument out of domain
    x=-340282346638528859811704183484516925440.000000

Le message « log: SING error » a été affiché par la bibliothèque C.

Dans l'exécution suivante, matherr() est appelée et renvoie une valeur non nulle :

    $ ./a.out 0.0 1
    matherr SING exception in log() function
            args:   0.000000, 0.000000
            retval: -340282346638528859811704183484516925440.000000
    x=-340282346638528859811704183484516925440.000000

Dans ce cas, la bibliothèque C n'a pas affiché de message et errno n'a pas été positionnée.

Dans l'exécution suivante, matherr() est appelée, modifie la valeur renvoyée par la fonction mathématique et renvoie une valeur non nulle :

    $ ./a.out 0.0 1 12345.0
    matherr SING exception in log() function
            args:   0.000000, 0.000000
            retval: -340282346638528859811704183484516925440.000000
    x=12345.000000

  Source du programme
    #define _SVID_SOURCE
    #include <errno.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>

    static int matherr_ret = 0;     /* Valeur que matherr()
                                       devrait renvoyer */
    static int change_retval = 0;   /* Voulez-vous que matherr() modifie la
                                       valeur renvoyée par la fonction ? */
    static double new_retval;       /* Nouvelle valeur renvoyée par la fonction */

    int
    matherr(struct exception *exc)
    {
        fprintf(stderr, "matherr %s exception in %s() function\n",
                (exc->type == DOMAIN) ?    "DOMAIN" :
                (exc->type == OVERFLOW) ?  "OVERFLOW" :
                (exc->type == UNDERFLOW) ? "UNDERFLOW" :
                (exc->type == SING) ?      "SING" :
                (exc->type == TLOSS) ?     "TLOSS" :
                (exc->type == PLOSS) ?     "PLOSS" : "???",
                exc->name);
        fprintf(stderr, "        args:   %f, %f\n",
                exc->arg1, exc->arg2);
        fprintf(stderr, "        retval: %f\n", exc->retval);

        if (change_retval)
            exc->retval = new_retval;

        return matherr_ret;
    }

    int
    main(int argc, char *argv[])
    {
        double x;

        if (argc < 2) {
            fprintf(stderr, "Usage: %s <argval>"
                    " [<matherr-ret> [<new-func-retval>]]\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        if (argc > 2) {
            _LIB_VERSION = _SVID_;
            matherr_ret = atoi(argv[2]);
        }

        if (argc > 3) {
            change_retval = 1;
            new_retval = atof(argv[3]);
        }

        x = log(atof(argv[1]));
        if (errno != 0)
            perror("errno");

        printf("x=%f\n", x);
        exit(EXIT_SUCCESS);
    }

VOIR AUSSI
fenv(3), math_error(7), standards(7)

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.