HOWTO · Csharp
Arrotondare un valore doppio a un valore intero in C#
In C#, puoi arrotondare un valore `double` a un intero usando `Math.Ceiling()`, `Math.Floor()` o `Math.Round()`, ciascuno con una regola diversa.
In questa pagina
Quando converti un double in int, scegli prima la regola di arrotondamento. Usa Math.Ceiling() per spostarti verso l’infinito positivo, Math.Floor() per spostarti verso l’infinito negativo e Math.Round() per scegliere il valore intero più vicino. Una conversione esplicita come (int)value tronca verso zero: non arrotonda.
I tre metodi matematici restituiscono un double con valore intero; se ti serve un int, converti il risultato. Se gli input possono essere grandi, verifica che il risultato rientri nell’intervallo di int prima della conversione.
Scegli la regola di arrotondamento prima di convertire in int
La direzione conta sia per i valori positivi sia per quelli negativi. Per esempio, Math.Ceiling(-8.3) si sposta a -8, mentre Math.Floor(-8.3) si sposta a -9. Nessuno dei due metodi si limita a «eliminare la parte frazionaria». Usa questo confronto per scegliere l’operazione più adatta alla tua applicazione:
| Operazione | Regola | Risultato di esempio per 8.3 |
Risultato di esempio per -8.3 |
|---|---|---|---|
Math.Ceiling(value) |
Verso l’infinito positivo | 9 |
-8 |
Math.Floor(value) |
Verso l’infinito negativo | 8 |
-9 |
Math.Round(value) |
Intero più vicino; per impostazione predefinita, i casi a metà vengono arrotondati al pari | 8 |
-8 |
(int)value |
Tronca verso zero | 8 |
-8 |
La tabella mostra i risultati prima della conversione: ogni metodo matematico restituisce un double. Per input compresi nell’intervallo degli interi, una conversione esplicita in int mantiene questi valori interi. La scelta giusta dipende da cosa rappresenta l’intero: un conteggio, un limite o una stima del valore più vicino possono richiedere regole diverse.
Esegui questo esempio autonomo:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
using System;
class Program
{
static void Main()
{
double value = 8.3;
double otherValue = -8.3;
Console.WriteLine($"Ceiling: {(int)Math.Ceiling(value)}, {(int)Math.Ceiling(otherValue)}");
Console.WriteLine($"Floor: {(int)Math.Floor(value)}, {(int)Math.Floor(otherValue)}");
Console.WriteLine($"Nearest: {(int)Math.Round(value)}, {(int)Math.Round(otherValue)}");
Console.WriteLine($"Cast: {(int)value}, {(int)otherValue}");
Console.WriteLine($"Midpoints: {(int)Math.Round(2.5)}, {(int)Math.Round(3.5)}, {(int)Math.Round(2.5, MidpointRounding.AwayFromZero)}");
}
}
Arrotonda verso l’alto con Math.Ceiling()
Math.Ceiling() restituisce il più piccolo double con valore intero maggiore o uguale all’input. Questo significa arrotondare verso l’infinito positivo: un valore frazionario positivo passa all’intero successivo, mentre un valore frazionario negativo passa all’intero più vicino allo zero. Converti il risultato in int solo dopo aver verificato che sia rappresentabile come int.
Usa questa regola quando il risultato non deve mai essere inferiore al valore originale, per esempio per determinare quanti contenitori interi servono a contenere una quantità. Ad esempio, Math.Ceiling(7.3) restituisce il double con valore intero 8; (int)Math.Ceiling(7.3) produce un intero se il valore rientra nell’intervallo di int. Se invece il requisito è «arrotondare lontano da zero», per i valori negativi Ceiling non applica questa regola.
Arrotonda verso il basso con Math.Floor()
Math.Floor() restituisce il più grande double con valore intero minore o uguale all’input. Arrotonda verso l’infinito negativo. Quindi Math.Floor(7.8) restituisce 7 e Math.Floor(-7.8) restituisce -8. La distinzione è importante: applicare il floor a un valore negativo non significa semplicemente eliminare le cifre frazionarie.
Usa Math.Floor() quando il risultato non deve superare l’input, per esempio per calcolare il numero di unità complete in una quantità misurata. Come con Ceiling, converti il double restituito in int solo se il risultato rientra nell’intervallo degli interi. Se vuoi eliminare la parte frazionaria verso zero, indipendentemente dal segno, usa una conversione o Math.Truncate().
Arrotonda all’intero più vicino con Math.Round()
Math.Round() seleziona il valore intero più vicino e lo restituisce come double. Per impostazione predefinita, nei casi a metà arrotonda al pari: quando un valore è esattamente a metà tra due interi, sceglie quello pari. Per esempio, Math.Round(2.5) sceglie 2, mentre Math.Round(3.5) sceglie 4. Questo riduce la distorsione direzionale quando si ripetono calcoli con valori a metà.
Per scegliere l’altra regola comune per i casi a metà, passa MidpointRounding.AwayFromZero: Math.Round(2.5, MidpointRounding.AwayFromZero) sceglie 3 e Math.Round(-2.5, MidpointRounding.AwayFromZero) sceglie -3. Questa opzione cambia il trattamento dei casi a metà, ma non fa sì che ogni valore venga arrotondato lontano da zero. Se serve, converti il risultato arrotondato in int, dopo averne verificato l’intervallo.
I numeri in virgola mobile binaria possono rappresentare alcune frazioni decimali solo in modo approssimato. Se un valore dovrebbe essere esattamente a metà, ma è stato calcolato a partire da altri valori in virgola mobile, il valore memorizzato potrebbe trovarsi leggermente da un lato o dall’altro del punto medio. Per regole che dipendono da quantità decimali esatte, valuta di rappresentare i dati con decimal e usare il corrispondente overload di Math.Round, selezionando comunque la modalità desiderata per i casi a metà.
Perché una conversione esplicita non arrotonda
Una conversione esplicita da double a int tronca la parte frazionaria verso zero. Per esempio, (int)8.9 diventa 8 e (int)(-8.9) diventa -8. Il secondo risultato è diverso da Math.Floor(-8.9), che restituisce -9, e dall’arrotondamento all’intero più vicino, che sceglie il valore più vicino secondo la regola selezionata per i casi a metà.
Usa una conversione quando vuoi troncare, non come scorciatoia per «arrotondare a un intero». Se l’input può essere fuori dall’intervallo di int, gestisci esplicitamente tale intervallo prima della conversione; altrimenti il risultato potrebbe non rappresentare il valore atteso dalla tua applicazione. In breve, scegli Math.Ceiling() per un limite verso l’infinito positivo, Math.Floor() per un limite verso l’infinito negativo, Math.Round() per l’intero più vicino e una conversione solo per troncare verso zero.