Quello che vorrei è un metodo per convertire un doppio in una stringa che arrotonda usando il metodo half-up - cioè se il decimale da arrotondare è 5, arrotonda sempre al numero successivo. Questo è il metodo standard di arrotondamento che la maggior parte delle persone si aspetta nella maggior parte delle situazioni.
Vorrei anche che fossero visualizzate solo le cifre significative, cioè non ci dovrebbero essere zeri finali.
So che un metodo per farlo è usare il metodo String.format
:
String.format("%.5g%n", 0.912385);
ritorna:
0.91239
che è ottimo, tuttavia visualizza sempre i numeri con 5 cifre decimali anche se non sono significativi:
String.format("%.5g%n", 0.912300);
ritorna:
0.91230
Un altro metodo è usare il DecimalFormatter
:
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
ritorna:
0.91238
Tuttavia, come potete vedere, questo usa l'arrotondamento mezzo pari. Cioè arrotonderà per difetto se la cifra precedente è pari. Quello che vorrei è questo:
0.912385 -> 0.91239
0.912300 -> 0.9123
Qual è il modo migliore per ottenere questo in Java?
Usa setRoundingMode
, imposta il RoundingMode
esplicitamente per gestire il tuo problema con il mezzo giro pari, poi usa il modello di formato per il tuo output richiesto.
Esempio:
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
dà l'output:
12
123.1235
0.23
0.1
2341234.2125
EDIT: La risposta originale non affronta la precisione dei valori doppi. Questo va bene se non ti interessa molto se si arrotonda per eccesso o per difetto. Ma se vuoi un arrotondamento accurato, allora devi prendere in considerazione la precisione prevista dei valori. I valori in virgola mobile hanno internamente una rappresentazione binaria. Questo significa che un valore come 2.77395 non ha in realtà quel valore esatto al suo interno. Può essere leggermente più grande o leggermente più piccolo. Se il valore interno è leggermente più piccolo, allora non arrotonderà a 2,7740. Per rimediare a questa situazione, dovete essere consapevoli della precisione dei valori con cui state lavorando, e aggiungere o sottrarre quel valore prima di arrotondare. Per esempio, quando sapete che i vostri valori sono precisi fino a 6 cifre, allora per arrotondare i valori a metà, aggiungete quella precisione al valore:
Double d = n.doubleValue() + 1e-6;
Per arrotondare verso il basso, sottrai l'accuratezza.
Supponendo che value
sia un double
, si può fare:
(double)Math.round(value * 100000d) / 100000d
Questo per una precisione di 5 cifre. Il numero di zeri indica il numero di decimali.