Funzioni di Classificazione e Manipolazione per i Numeri in Virgola Mobile in Linguaggio C
- Lo standard C fornisce macro per classificare i numeri in virgola mobile in categorie come normali, subnormali, infiniti e NaN.
- Le macro di classificazione includono
fpclassify,isfinite,isinf,isnan,isnormalesignbit. - Lo standard C offre anche funzioni per manipolare i numeri in virgola mobile a basso livello, come
copysign,scalbn,nextafterenexttoward. - Le funzioni di manipolazione consentono di copiare il segno, moltiplicare per potenze di due e trovare il numero rappresentabile più vicino a un dato numero in virgola mobile.
Macro di Classificazione dei Numeri in Virgola Mobile
Lo standard C fornisce diverse macro per classificare i numeri in virgola mobile. Queste macro sono definite nell'header <math.h>.
Lo scopo di queste macro parametriche è quello di determinare se un numero in virgola mobile è un numero normale oppure rappresenta un valore speciale come infinito o NaN (Not a Number).
Tali macro prendono in ingresso un argomento di tipo double, float o long double e restituiscono un valore intero che indica la classificazione del numero.
Tali macro sono:
-
int fpclassify(real x);Questa macro prende in ingresso un numero in virgola mobile
xdi qualsiasi tipo (double,floatolong double) e restituisce un valore intero che indica la classificazione del numero. I valori di ritorno possibili sono:FP_INFINITE: sexrappresenta l'infinito positivo o negativo.FP_NAN: sexrappresenta un valore NaN (Not a Number).FP_NORMAL: sexè un numero normale.FP_SUBNORMAL: sexè un numero subnormale (denormalizzato).FP_ZERO: sexè zero (positivo o negativo).
-
int isfinite(real x);Questa macro restituisce un valore diverso da zero (vero) se il numero in virgola mobile
xè finito (cioè non è infinito né NaN), altrimenti restituisce zero (falso). -
int isinf(real x);Questa macro restituisce un valore diverso da zero (vero) se il numero in virgola mobile
xrappresenta l'infinito positivo o negativo, altrimenti restituisce zero (falso). -
int isnan(real x);Questa macro restituisce un valore diverso da zero (vero) se il numero in virgola mobile
xrappresenta un valore NaN (Not a Number), altrimenti restituisce zero (falso). -
int isnormal(real x);Questa macro restituisce un valore diverso da zero (vero) se il numero in virgola mobile
xè un numero normale, altrimenti restituisce zero (falso). -
int signbit(real x);Quest'ultima macro è leggermente differente rispetto alle altre. Essa restituisce un valore diverso da zero (vero) se il bit di segno del numero in virgola mobile
xè impostato (cioè sexè negativo), altrimenti restituisce zero (falso). Questa macro può essere utilizzata per determinare il segno di numeri speciali come zero, infinito e NaN.
Queste macro sono utili per gestire correttamente i numeri in virgola mobile in situazioni in cui è necessario distinguere tra numeri normali, subnormali, infiniti e NaN, garantendo così un comportamento prevedibile e sicuro nelle operazioni matematiche.
Funzioni di Manipolazione dei Numeri in Virgola Mobile
Oltre alle macro di classificazione, lo standard C fornisce anche diverse funzioni per manipolare i numeri in virgola mobile.
Con il verbo "manipolare" si intende eseguire operazioni che lavorano a basso livello sui numeri in virgola mobile.
Le operazioni di manipolazione includono:
-
Copia del segno:
Le funzioni:
double copysign(double x, double y);float copysignf(float x, float y);long double copysignl(long double x, long double y);
Queste funzioni restituiscono un numero in virgola mobile con il valore assoluto di
xe il segno diy. In altre parole, il risultato avrà lo stesso valore numerico dix, ma il segno (positivo o negativo) sarà quello diy. -
Moltiplicazione per potenze di due:
Le funzioni:
double scalbn(double x, int n);float scalbnf(float x, int n);long double scalbnl(long double x, int n);
Queste funzioni restituiscono il risultato di
xmoltiplicato per 2 elevato alla potenza din. In pratica, queste funzioni modificano l'esponente del numero in virgola mobilexaggiungendonall'esponente corrente.Ad esempio, se
xè 1.5 (che è rappresentato come) e nè 2, il risultato sarà 6.0 (che è rappresentato come). Questa operazione è molto più efficiente rispetto alla moltiplicazione diretta per potenze di due, poiché agisce direttamente sull'esponente del numero in virgola mobile che è in base 2.
-
Funzioni di ricerca dei numeri rappresentabili:
Anche se i numeri in virgola mobile vengono usati per rappresentare numeri reali, non tutti i numeri reali possono essere rappresentati esattamente in questo formato a causa delle limitazioni di precisione. Anzi, una quantità infinita di numeri reali non può essere rappresentata esattamente in virgola mobile.
Dato che i numeri
double,floatelong doublehanno un numero di bit limitato per rappresentare la mantissa e l'esponente, esistono solo un numero finito di valori che possono essere rappresentati esattamente. Quindi, dato un numero floating point è sempre possibile trovare il numero rappresentabile più vicino ad esso.In tal senso, lo standard C fornisce le seguenti funzioni:
double nextafter(double x, double y);float nextafterf(float x, float y);long double nextafterl(long double x, long double y);double nexttoward(double x, long double y);float nexttowardf(float x, long double y);long double nexttowardl(long double x, long double y);
Le funzioni
nextafterenexttowardrestituiscono il numero in virgola mobile rappresentabile più vicino axnella direzione diy. Sexè uguale ay, viene restituitoy.La differenza tra le due funzioni è che
nextafteraccetta entrambi gli argomenti dello stesso tipo (ad esempio, entrambidouble), mentrenexttowardaccetta il primo argomento di tipodouble,floatolong double, e il secondo argomento di tipolong double. Questo permette anexttowarddi fornire una maggiore precisione nella direzione verso cui si desidera trovare il numero rappresentabile più vicino.