Funzioni Matematiche della Libreria Standard in Linguaggio C
- La libreria matematica standard C, definita nell'header
<math.h>, offre una vasta gamma di funzioni matematiche per eseguire operazioni comuni come calcoli trigonometrici, esponenziali, logaritmici e altro ancora. - La libreria include costanti numeriche utili come
M_PIper il valore die M_Eper il valore di. - Le funzioni matematiche sono disponibili in tre varianti per supportare i tipi di dati
float,doubleelong double, consentendo una maggiore flessibilità nell'uso delle precisioni numeriche.
Costanti numeriche
La libreria matematica standard C definisce alcune costanti numeriche utili per le operazioni matematiche. Queste costanti sono definite come macro nell'header <math.h> e includono:
| Macro | Valore approssimato | Descrizione |
|---|---|---|
M_PI |
3.14159265358979323846 | Valore di |
M_PI_2 |
1.57079632679489661923 | Valore di |
M_PI_4 |
0.78539816339744830962 | Valore di |
M_1_PI |
0.31830988618379067154 | Valore di |
M_2_PI |
0.63661977236758134308 | Valore di |
M_2_SQRTPI |
1.12837916709551257390 | Valore di |
M_E |
2.71828182845904523536 | Valore di |
M_SQRT2 |
1.41421356237309504880 | Valore di |
M_SQRT1_2 |
0.70710678118654752440 | Valore di |
M_LN2 |
0.69314718055994530942 | Valore di |
M_LN10 |
2.30258509299404568402 | Valore di |
M_LOG2E |
1.44269504088896340736 | Valore di |
M_LOG10E |
0.43429448190325182765 | Valore di |
In realtà, tali macro non sono parte dello standard C, ma sono ampiamente supportate dai compilatori più comuni come estensioni. Tuttavia, è importante notare che non tutti i compilatori garantiscono la presenza di queste macro, quindi è buona pratica verificare la documentazione del compilatore in uso.
Funzioni Trigonometriche
La libreria matematica standard C fornisce diverse funzioni trigonometriche per calcolare i valori delle funzioni seno, coseno, tangente e le loro inverse:
| Funzione | Descrizione | Note |
|---|---|---|
sinf(float x) |
float. |
C99 |
sin(double x) |
double. |
|
sinl(long double x) |
long double. |
C99 |
cosf(float x) |
float. |
C99 |
cos(double x) |
double. |
|
cosl(long double x) |
long double. |
C99 |
tanf(float x) |
float. |
C99 |
tan(double x) |
double. |
|
tanl(long double x) |
long double. |
C99 |
| Funzione | Descrizione | Note |
|---|---|---|
asinf(float x) |
float. |
C99 |
asin(double x) |
double. |
|
asinl(long double x) |
long double. |
C99 |
acosf(float x) |
float. |
C99 |
acos(double x) |
double. |
|
acosl(long double x) |
long double. |
C99 |
atanf(float x) |
float. |
C99 |
atan(double x) |
double. |
|
atanl(long double x) |
long double. |
C99 |
atan2f(float y, float x) |
float. |
C99 |
atan2(double y, double x) |
double. |
|
atan2l(long double y, long double x) |
long double. |
C99 |
Un'importante osservazione riguarda l'unità di misura degli angoli utilizzata da queste funzioni. Tutte le funzioni trigonometriche della libreria matematica standard C operano in radianti, non in gradi. Pertanto, se si desidera utilizzare gradi, è necessario convertire i valori tra gradi e radianti utilizzando le seguenti formule:
Inoltre, spesso a causa di arrotondamenti numerici, non è detto che il risultato fornito dalla funzione cos, ad esempio, passato in ingresso alla funzione acos restituisca esattamente il valore originale.
Inoltre, la funzione acos restituisce valori solo nell'intervallo asin e atan restituiscono valori nell'intervallo
La funzione atan2 è particolarmente utile perché considera il segno di entrambi gli argomenti per determinare il quadrante corretto dell'angolo risultante, restituendo valori nell'intervallo atan(x) equivale a atan2(x, 1.0).
Funzioni Iperboliche
La libreria matematica standard C include anche funzioni per calcolare le funzioni iperboliche e le loro inverse:
| Funzione | Descrizione | Note |
|---|---|---|
sinhf(float x) |
float. |
C99 |
sinh(double x) |
double. |
|
sinhl(long double x) |
long double. |
C99 |
coshf(float x) |
float. |
C99 |
cosh(double x) |
double. |
|
coshl(long double x) |
long double. |
C99 |
tanhf(float x) |
float. |
C99 |
tanh(double x) |
double. |
|
tanhl(long double x) |
long double. |
C99 |
| Funzione | Descrizione | Note |
|---|---|---|
asinhf(float x) |
float. |
C99 |
asinh(double x) |
double. |
C99 |
asinhl(long double x) |
long double. |
C99 |
acoshf(float x) |
float. |
C99 |
acosh(double x) |
double. |
C99 |
acoshl(long double x) |
long double. |
C99 |
atanhf(float x) |
float. |
C99 |
atanh(double x) |
double. |
C99 |
atanhl(long double x) |
long double. |
C99 |
Si noti che anche in questo caso, le funzioni iperboliche operano su valori in radianti e non in gradi.
Funzioni Esponenziali e Logaritmiche
La libreria matematica standard C fornisce funzioni per calcolare esponenziali e logaritmi:
| Funzione | Descrizione | Note |
|---|---|---|
expf(float x) |
float. |
C99 |
exp(double x) |
double. |
|
expl(long double x) |
long double. |
C99 |
logf(float x) |
float. |
C99 |
log(double x) |
double. |
|
logl(long double x) |
long double. |
C99 |
log10f(float x) |
float. |
C99 |
log10(double x) |
double. |
|
log10l(long double x) |
long double. |
C99 |
exp2f(float x) |
float. |
C99 |
exp2(double x) |
double. |
C99 |
exp2l(long double x) |
long double. |
C99 |
expm1f(float x) |
float. |
C99 |
expm1(double x) |
double. |
C99 |
expm1l(long double x) |
long double. |
C99 |
log1pf(float x) |
float. |
C99 |
log1p(double x) |
double. |
C99 |
log1pl(long double x) |
long double. |
C99 |
log2f(float x) |
float. |
C99 |
log2(double x) |
double. |
C99 |
log2l(long double x) |
long double. |
C99 |
ilogbf(float x) |
Parte intera di int. |
C99 |
ilogb(double x) |
Parte intera di int. |
C99 |
ilogbl(long double x) |
Parte intera di int. |
C99 |
logbf(float x) |
Esponente di int. |
C99 |
logb(double x) |
Esponente di int. |
C99 |
logbl(long double x) |
Esponente di int. |
C99 |
Tutte queste funzioni hanno a che fare con l'esponenziale naturale (base
Inoltre, calcolare il logaritmo di numeri molto vicini a 1 può portare a errori di arrotondamento significativi. Per questo motivo, le funzioni log1p e expm1 sono state introdotte per fornire una maggiore precisione in questi casi specifici.
Per calcolare il logaritmo in basi diverse da
Quindi, ad esempio, per calcolare il logaritmo in base 3 di un numero x, si può utilizzare:
double log_base_3(double x) {
return log(x) / log(3.0);
}
Funzioni di Potenza e Radice
La libreria matematica standard C include funzioni per calcolare potenze e radici:
| Funzione | Descrizione | Note |
|---|---|---|
powf(float b, float e) |
Calcola float. |
C99 |
pow(double b, double e) |
Calcola double. |
|
powl(long double b, long double e) |
Calcola long double. |
C99 |
sqrtf(float x) |
Calcola float. |
C99 |
sqrt(double x) |
Calcola double. |
|
sqrtl(long double x) |
Calcola long double. |
C99 |
frexpf(float x, int *esponente) |
Scompone x in frazione e potenza di 2. Restituisce float. |
C99 |
frexp(double x, int *esponente) |
Scompone x in frazione e potenza di 2. Restituisce double. |
|
frexpl(long double x, int *esponente) |
Scompone x in frazione e potenza di 2. Restituisce long double. |
C99 |
ldexpf(float f, int e) |
Calcola float. |
C99 |
ldexp(double f, int e) |
Calcola double. |
|
ldexpl(long double f, int e) |
Calcola long double. |
C99 |
cbrtf(float x) |
Calcola float. |
C99 |
cbrt(double x) |
Calcola double. |
C99 |
cbrtl(long double x) |
Calcola long double. |
C99 |
hypotf(float x, float y) |
Calcola float. |
C99 |
hypot(double x, double y) |
Calcola double. |
|
hypotl(long double x, long double y) |
Calcola long double. |
C99 |
Funzioni per il Valore Assoluto e il Segno
La libreria matematica standard C include funzioni per calcolare il valore assoluto e il segno di un numero:
| Funzione | Descrizione | Note |
|---|---|---|
fabsf(float x) |
Calcola il valore assoluto di x. Restituisce float. |
C99 |
fabs(double x) |
Calcola il valore assoluto di x. Restituisce double. |
|
fabsl(long double x) |
Calcola il valore assoluto di x. Restituisce long double. |
C99 |
copysignf(float x, float y) |
Restituisce x con il segno di y. Restituisce float. |
C99 |
copysign(double x, double y) |
Restituisce x con il segno di y. Restituisce double. |
|
copysignl(long double x, long double y) |
Restituisce x con il segno di y. Restituisce long double. |
C99 |
signbitf(float x) |
Restituisce vero se il segno di x è negativo. |
Restituisce int. |
signbit(double x) |
Restituisce vero se il segno di x è negativo. |
Restituisce int. |
signbitl(long double x) |
Restituisce vero se il segno di x è negativo. |
Restituisce int. |
Le funzioni copysign sono particolarmente utili quando si desidera manipolare il segno di un numero senza alterarne il valore assoluto.
Ad esempio, copysign(x, 1.0) restituisce il valore assoluto di x, mentre copysign(x, -1.0) restituisce il valore assoluto di x con segno negativo.
Le funzioni signbit, invece, sono utili per verificare se un numero è negativo, indipendentemente dal suo valore assoluto. Queste funzioni sono molto più affidabili rispetto a un semplice confronto con zero, poiché considerano anche il caso di zero negativo rappresentato in virgola mobile.
Funzione Gamma e Funzione di Errore Standard
La libreria matematica standard C include funzioni per calcolare la funzione gamma e la funzione di errore:
| Funzione | Descrizione | Note |
|---|---|---|
tgammaf(float x) |
Calcola la funzione gamma di x. Restituisce float. |
C99 |
tgamma(double x) |
Calcola la funzione gamma di x. Restituisce double. |
|
tgammal(long double x) |
Calcola la funzione gamma di x. Restituisce long double. |
C99 |
lgammaf(float x) |
Calcola il logaritmo naturale della funzione gamma di x. Restituisce float. |
C99 |
lgamma(double x) |
Calcola il logaritmo naturale della funzione gamma di x. Restituisce double. |
|
lgammal(long double x) |
Calcola il logaritmo naturale della funzione gamma di x. Restituisce long double. |
C99 |
erff(float x) |
Calcola la funzione di errore di x. Restituisce float. |
C99 |
erf(double x) |
Calcola la funzione di errore di x. Restituisce double. |
|
erfl(long double x) |
Calcola la funzione di errore di x. Restituisce long double. |
C99 |
erfcf(float x) |
Calcola la funzione di errore complementare di x. Restituisce float. |
C99 |
erfc(double x) |
Calcola la funzione di errore complementare di x. Restituisce double. |
|
erfcl(long double x) |
Calcola la funzione di errore complementare di x. Restituisce long double. |
C99 |
lgamma_r(double x, int *signgamp) |
Calcola il logaritmo naturale della funzione gamma di x e imposta il segno in signgamp. Restituisce double. |
C99 |
Alcune osservazioni importanti riguardo a queste funzioni:
-
Le funzioni
erf,erffeerflcalcolano la funzione di errore, che è utile in statistica e probabilità: -
Le funzioni
erfc,erccfeerfclcalcolano la funzione di errore complementare: -
La funzione gamma,
, è una generalizzazione della funzione fattoriale per numeri reali e complessi. Per numeri interi positivi vale: Per valori reali e complessi, la funzione gamma è più complessa e viene definita tramite un'integrale improprio:
Le funzioni
tgammaelgammacalcolano rispettivamente la funzione gamma e il suo logaritmo naturale:tgamma(x)restituiscelgamma(x)restituisce
La funzione
lgamma_rfornisce anche il segno della funzione gamma tramite il parametrosigngamp. Spesso usare la funzione logaritmica è preferibile per evitare problemi di overflow con valori grandi dix.
Funzioni per la moltiplicazione e somma combinate (Fused Multiply-Add)
Un'importante funzionalità offerta dalla libreria matematica standard C è la possibilità di eseguire operazioni di moltiplicazione e somma combinate, note come Fused Multiply-Add (FMA), Moltiplicazione e Somma Fuse.
Le funzioni FMA sono:
| Funzione | Descrizione | Note |
|---|---|---|
fmaf(float x, float y, float z) |
Calcola (x * y) + z con un'unica operazione. Restituisce float. |
C99 |
fma(double x, double y, double z) |
Calcola (x * y) + z con un'unica operazione. Restituisce double. |
C99 |
fmal(long double x, long double y, long double z) |
Calcola (x * y) + z con un'unica operazione. Restituisce long double. |
C99 |
In pratica, tali funzioni, dati i numeri
Queste funzioni sono state aggiunte allo standard dal momento che molte CPU moderne offrono in hardware l'operazione FMA che moltiplica e somma in un colpo solo. Chiamando tale funzione, stiamo dicendo al compilatore che vogliamo sfruttare l'istruzine hardware corrispondente (se disponibile) che ha due vantaggi:
- Se presente, essendo svolta in hardware tale operazione è più veloce rispetto ad effettuare le due operazioni separatamente;
- Tale istruzione esegue un'operazione di arrotondamento una volta sola, anziché due, quindi produce un risultato più accurato.
Essa è particolarmente utile in quegli algoritmi numerici che effettuano una serie di moltiplicazioni e addizioni. Ad esempio gli algoritmi per il calcolo del prodotto scalare tra due vettori, la moltiplicazione di due matrici oppure il calcolo della FFT (Fast Fourier Transform o Trasformata di Fourier Veloce).
Per sapere se la piattaforma sottostante e il compilatore supportano tale funzione, si può controllare se la macro FP_FAST_FMA è stata definita. In caso affermativo, chiamare fma dovrebbe essere più veloce di (o almeno veloce quanto) effettuare un'operazione di moltiplicazione e somma distinte.
Esistono anche le macro FP_FAST_FMAF e FP_FAST_FMAL che svolgono lo stesso ruolo per le funzioni fmaf e fmal rispettivamente.