Funzioni Matematiche di Arrotondamento e Resto in Linguaggio C
- La libreria matematica standard di C fornisce diverse funzioni per arrotondare numeri in virgola mobile secondo regole specifiche:
ceil,floor,trunc,round,nearbyinterint. - Le funzioni di arrotondamento possono restituire il risultato come un valore in virgola mobile o come un valore intero:
lroundellround. - La libreria matematica standard di C fornisce anche funzioni per calcolare il resto della divisione tra numeri in virgola mobile:
fmod,remaindereremquo.
Funzioni di Arrotondamento
La libreria matematica standard di C fornisce diverse funzioni per approssimare i numeri in virgola mobile.
Tutte queste funzioni sono dichiarate nell'header <math.h>.
Possiamo dividere queste funzioni in tre categorie:
-
Funzioni che arrotondano un numero in virgola mobile verso l'alto o verso il basso e lo restituiscono come un valore in virgola mobile:
Funzione Descrizione Note double ceil(double x);Restituisce il più piccolo intero maggiore o uguale a x.double ceilf(float x);Versione floatdiceil.C99 double ceill(long double x);Versione long doublediceil.C99 double floor(double x);Restituisce il più grande intero minore o uguale a x.double floorf(float x);Versione floatdifloor.C99 double floorl(long double x);Versione long doubledifloor.C99 Tabella 1: Funzioni ceil e floor della libreria matematica standard. La funzione
ceile le sue varianti restituiscono il più piccolo intero (in forma didouble) che è maggiore o uguale al valore passato come argomento. Infatti il nome "ceil" deriva dalla parola inglese "ceiling", che significa "soffitto" o "parte superiore".Viceversa, la funzione
floore le sue varianti restituiscono il più grande intero (in forma didouble) che è minore o uguale al valore passato come argomento. Il nome "floor" deriva dalla parola inglese "floor", che significa "pavimento" o "parte inferiore".Matematicamente, possiamo esprimere il comportamento di queste funzioni come segue:
Ad esempio:
ceil(4.2)restituisce5.0ceil(-4.2)restituisce-4.0floor(4.2)restituisce4.0floor(-4.2)restituisce-5.0
In altre parole, la funzione
ceilarrotonda sempre verso l'alto, mentre la funzionefloorarrotonda sempre verso il basso. -
Funzioni che arrotondano un numero in virgola mobile sempre verso lo zero e lo restituiscono come un valore in virgola mobile:
Funzione Descrizione Note double trunc(double x);Restituisce la parte intera di x, arrotondata verso zero.C99 double truncf(float x);Versione floatditrunc.C99 double truncl(long double x);Versione long doubleditrunc.C99 Tabella 2: Funzioni trunc della libreria matematica standard. La funzione
trunce le sue varianti restituiscono la parte intera del numero passato come argomento, arrotondata sempre verso zero. Ad esempio:trunc(4.7)restituisce4.0trunc(-4.7)restituisce-4.0
In altre parole, la funzione
truncelimina la parte decimale del numero indipendentemente dal segno del numero stesso. Pertanto,truncarrotonda sempre verso zero.Infatti, possiamo esprimere il comportamento di questa funzione come segue:
-
Funzioni che arrotondano un numero in virgola mobile lontano dallo zero e lo restituiscono come un valore in virgola mobile:
Funzione Descrizione Note double round(double x);Restituisce il valore di xarrotondato all'intero più vicino. In caso di parità, arrotonda lontano da zero.C99 double roundf(float x);Versione floatdiround.C99 double roundl(long double x);Versione long doublediround.C99 Tabella 3: Funzioni round della libreria matematica standard. La funzione
rounde le sue varianti arrotondano il numero passato come argomento all'intero più vicino. In caso di parità (quando la parte decimale è esattamente 0.5), la funzione arrotonda lontano da zero. Ad esempio:round(4.5)restituisce5.0round(4.4)restituisce4.0round(-4.5)restituisce-5.0round(-4.4)restituisce-4.0
In altre parole, la funzione
roundsegue la regola dell'arrotondamento standard, ma in caso di parità, si assicura che il risultato sia sempre più lontano da zero.Infatti, possiamo esprimere il comportamento di questa funzione come segue:
Oltre a queste funzioni che arrotondano in base a regole specifiche, la libreria fornisce anche delle funzioni per arrotondare un numero secondo la modalità di arrotondamento corrente definita nell'ambiente di esecuzione matematica:
| Funzione | Descrizione | Note |
|---|---|---|
double nearbyint(double x); |
Restituisce il valore di x arrotondato secondo la modalità di arrotondamento corrente. Non genera eccezioni di overflow. |
C99 |
double nearbyintf(float x); |
Versione float di nearbyint. |
C99 |
double nearbyintl(long double x); |
Versione long double di nearbyint. |
C99 |
double rint(double x); |
Restituisce il valore di x arrotondato secondo la modalità di arrotondamento corrente. Può generare eccezioni di inexact o overflow. |
C99 |
double rintf(float x); |
Versione float di rint. |
C99 |
double rintl(long double x); |
Versione long double di rint. |
C99 |
Queste funzioni arrotondano il numero passato come argomento secondo la modalità di arrotondamento corrente definita nell'ambiente di esecuzione matematica. La differenza principale tra le due è che nearbyint non genera eccezioni di overflow, mentre rint può generare eccezioni di inexact o overflow.
In pratica, a seconda della modalità di arrotondamento corrente, queste funzioni possono comportarsi come ceil, floor, trunc o round.
Funzioni di Arrotondamento a Intero
Le funzioni viste sopra arrotondano i numeri in virgola mobile ad un intero secondo regole specifiche, ma restituiscono comunque un valore in virgola mobile.
La libreria matematica standard di C fornisce anche funzioni che arrotondano i numeri in virgola mobile ad un intero e restituiscono il risultato come un valore intero.
| Funzione | Descrizione | Note |
|---|---|---|
long int lround(double x); |
Restituisce il valore di x arrotondato all'intero più vicino come long int. In caso di parità, arrotonda lontano da zero. |
C99 |
long int lroundf(float x); |
Versione float di lround. |
C99 |
long int lroundl(long double x); |
Versione long double di lround. |
C99 |
long int llround(double x); |
Restituisce il valore di x arrotondato all'intero più vicino come long long int. In caso di parità, arrotonda lontano da zero. |
C99 |
long int llroundf(float x); |
Versione float di llround. |
C99 |
long int llroundl(long double x); |
Versione long double di llround. |
C99 |
Tali funzioni si comportano in modo simile alla funzione round vista in precedenza, arrotondando il numero passato come argomento all'intero più vicino. In caso di parità, arrotondano lontano da zero.
La differenza, però, è che queste funzioni restituiscono il risultato come un valore intero (long int o long long int) invece che come un valore in virgola mobile.
Ad esempio:
lround(4.5)restituisce5lround(4.4)restituisce4llround(-4.5)restituisce-5llround(-4.4)restituisce-4
Funzione di Resto
In linguaggio C, esiste l'operatore di modulo (o operatore di resto) % che calcola il resto della divisione tra due numeri interi.
Tuttavia, non è possibile applicare l'operatore % direttamente a numeri in virgola mobile. Per questo motivo, la libreria matematica standard di C fornisce delle funzioni specifiche per calcolare il resto della divisione tra due numeri in virgola mobile.
| Funzione | Descrizione | Note |
|---|---|---|
double fmod(double x, double y); |
Restituisce il resto della divisione di x per y. |
|
double fmodf(float x, float y); |
Versione float di fmod. |
C99 |
double fmodl(long double x, long double y); |
Versione long double di fmod. |
C99 |
double remainder(double x, double y); |
Restituisce il resto della divisione di x per y, dove il quoziente è stato arrotondato all'intero più vicino. |
C99 |
double remainderf(float x, float y); |
Versione float di remainder. |
C99 |
double remainderl(long double x, long double y); |
Versione long double di remainder. |
C99 |
double remquo(double x, double y, int *quo); |
Identica a remainder ma salva anche il quoziente in *quo. |
C99 |
double remquof(float x, float y, int *quo); |
Versione float di remquo. |
C99 |
double remquol(long double x, long double y, int *quo); |
Versione long double di remquo. |
C99 |
Le funzioni della famiglia fmod calcolano il resto della divisione di x per y secondo la definizione matematica standard del modulo. Ad esempio, fmod(5.3, 2.0) restituisce 1.3, poiché 5.3 = 2.0 * 2 + 1.3.
Le funzioni della famiglia remainder calcolano il resto della divisione di x per y in modo particolare. Per capire come funziona, definiamo x diviso y, arrotondato al più vicino intero. La funzione remainder restituisce quindi il valore:
Ad esempio, remainder(5.3, 2.0) restituisce -0.7, poiché il quoziente arrotondato è 3 (il più vicino intero a 5.3 / 2.0 = 2.65), e quindi 5.3 - 3 * 2.0 = -0.7. Se avessimo usato fmod(5.3, 2.0), avremmo ottenuto 1.3.
La funzione remquo è simile a remainder, ma in aggiunta salva il quoziente arrotondato in un intero passato come terzo argomento. Questo può essere utile se si desidera conoscere sia il resto che il quoziente della divisione.
Ad esempio:
#include <stdio.h>
#include <math.h>
int main() {
double x = 5.3;
double y = 2.0;
int quo;
double r1 = fmod(x, y);
double r2 = remainder(x, y);
double r3 = remquo(x, y, &quo);
printf("fmod(%.1f, %.1f) = %.1f\n", x, y, r1);
printf("remainder(%.1f, %.1f) = %.1f\n", x, y, r2);
printf("remquo(%.1f, %.1f) = %.1f, quo = %d\n", x, y, r3, quo);
return 0;
}
L'output sarà:
fmod(5.3, 2.0) = 1.3
remainder(5.3, 2.0) = -0.7
remquo(5.3, 2.0) = -0.7, quo = 3