math_error(7)

NUME
math_error - detectează erorile din funcțiile matematice

SINOPSIS
#include <math.h>
#include <errno.h>
#include <fenv.h>

DESCRIERE
Atunci când apare o eroare, majoritatea funcțiilor de bibliotecă indică acest fapt prin returnarea unei valori speciale (de exemplu, -1 sau NULL). Deoarece în mod obișnuit returnează un număr în virgulă mobilă, funcțiile matematice declarate în <math.h> indică o eroare folosind alte mecanisme. Există două mecanisme de semnalizare a erorilor: cel mai vechi definește errno; cel mai nou utilizează mecanismul de excepție în virgulă mobilă (utilizarea lui feclearexcept(3) și fetestexcept(3), așa cum este prezentat mai jos) descris în fenv(3).

Un program portabil care trebuie să verifice o eroare dintr-o funcție matematică ar trebui să stabilească errno la zero și să facă următorul apel

    feclearexcept(FE_ALL_EXCEPT);

înainte de a apela o funcție matematică.

La revenirea din funcția matematică, dacă errno este diferită de zero, sau dacă apelul următor (a se vedea fenv(3)) returnează un rezultat diferit de zero,

    fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW |
                 FE_UNDERFLOW);

atunci s-a produs o eroare în funcția matematică.

Condițiile de eroare care pot apărea pentru funcțiile matematice sunt descrise mai jos.

  Eroare de domeniu
O eroare de domeniu apare atunci când o funcție matematică este furnizată cu un argument a cărui valoare se află în afara domeniului pentru care este definită funcția (de exemplu, dând un argument negativ lui log(3)). Atunci când apare o eroare de domeniu, funcțiile matematice returnează în mod obișnuit un NaN (deși unele funcții returnează o valoare diferită în acest caz); errno este stabilită la EDOM și se generează o excepție „nevalidă” (FE_INVALID) în virgulă mobilă.

  Eroare de pol (semn)
O eroare de pol apare atunci când rezultatul matematic al unei funcții este un infinit exact (de exemplu, logaritmul lui 0 este un infinit negativ). Atunci când apare o eroare de pol, funcția returnează valoarea (cu semn) HUGE_VAL, HUGE_VALF sau HUGE_VALL, în funcție de tipul rezultatului funcției: double, float sau long double. Semnul rezultatului este cel care este corect din punct de vedere matematic pentru funcția respectivă. errno este stabilită la ERANGE și se generează o excepție de „împărțire la zero” (FE_DIVBYZERO) în virgulă mobilă.

  Eroare de interval
O eroare de interval apare atunci când magnitudinea rezultatului funcției înseamnă că acesta nu poate fi reprezentat în tipul de rezultat al funcției. Valoarea de returnare a funcției depinde de faptul dacă eroarea de interval a fost o depășire a limitei maxime sau o depășire a limitei minime.

Un rezultat flotant de depășire a limitei maxime dacă rezultatul este finit, dar este prea mare pentru a fi reprezentat în tipul de rezultat. Atunci când se produce o depășire, funcția returnează valoarea HUGE_VAL, HUGE_VALF sau HUGE_VALL, în funcție de faptul că tipul rezultatului funcției este double, float sau long double. errno este stabilită la ERANGE și se generează o excepție de „depășire a limitei maxime” (FE_OVERFLOW) în virgulă mobilă.

Un rezultat flotant de depășire a limitei minime dacă rezultatul este prea mic pentru a fi reprezentat în tipul de rezultat. În cazul în care se produce o depășire a limitei minime, o funcție matematică returnează de obicei 0,0 (C99 spune că o funcție trebuie să returneze „o valoare definită de implementare a cărei mărime nu este mai mare decât cel mai mic număr pozitiv normalizat în tipul specificat”). errno poate fi stabilită la ERANGE și poate fi generată o excepție „depășire a limitei minime” (FE_UNDERFLOW) în virgulă mobilă.

Unele funcții generează o eroare de interval în cazul în care valoarea argumentului furnizat sau rezultatul corect al funcției ar fi subnormal. O valoare subnormală este o valoare diferită de zero, dar cu o magnitudine atât de mică încât nu poate fi prezentată în formă normalizată (adică cu un 1 în cel mai semnificativ bit al semnificantului). Reprezentarea unui număr subnormal va conține unul sau mai multe zerouri la început în semnificație.

NOTE
Identificatorul math_errhandling specificat de C99 și POSIX.1 nu este acceptat de glibc. Acest identificator ar trebui să indice care dintre cele două mecanisme de notificare a erorilor (errno, excepții recuperabile prin fetestexcept(3)) este utilizat. Standardele impun ca cel puțin unul dintre ele să fie utilizat, dar permit ca ambele să fie disponibile. Situația actuală (glibc 2.8) în cadrul glibc este dezordonată. Majoritatea funcțiilor (dar nu toate) ridică excepții în caz de eroare. Unele stabilesc, de asemenea, errno. Câteva funcții configurează errno, dar nu generează o excepție. Foarte puține funcții nu fac nici una, nici alta. Consultați paginile de manual individuale pentru detalii.

Pentru a evita complexitatea utilizării errno și fetestexcept(3) pentru verificarea erorilor, se recomandă adesea să se verifice dacă există valori de argument greșite înainte de fiecare apel. De exemplu, codul următor se asigură că argumentul lui log(3) nu este un NaN și nu este zero (o eroare de pol) sau mai mic decât zero (o eroare de domeniu):

    double x, r;

    if (isnan(x) || islessequal(x, 0)) {
        /* Rezolvă problemele cu NaN / eroare de pol / eroare de domeniu */
    }

    r = log(x);

Discuția de pe această pagină nu se aplică funcțiilor matematice complexe (de exemplu, cele declarate de <complex.h>), care, în general, nu sunt obligate să returneze erori prin C99 și POSIX.1.

Opțiunea gcc(1) -fno-math-errno face ca executabilul să utilizeze implementări ale unor funcții matematice care sunt mai rapide decât implementările standard, dar nu configurează errno în caz de eroare; (opțiunea gcc(1) -ffast-math activează, de asemenea, -fno-math-errno). O eroare poate fi în continuare testată folosind fetestexcept(3).

CONSULTAȚI ȘI
gcc(1), errno(3), fenv(3), fpclassify(3), INFINITY(3), isgreater(3), matherr(3), nan(3)

info libc

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.