Java BigDecimal: arrotondare al valore intero più vicino


89

Ho bisogno dei seguenti risultati

100.12 -> 100.00
100.44 -> 100.00
100.50 -> 101.00
100.75 -> 101.00

.round()o .setScale()? Come posso procedere?

Risposte:


151

È possibile utilizzare setScale()per ridurre il numero di cifre frazionarie a zero. Supponendo che valuecontenga il valore da arrotondare:

BigDecimal scaled = value.setScale(0, RoundingMode.HALF_UP);
System.out.println(value + " -> " + scaled);

L'utilizzo round()è un po 'più complicato in quanto richiede di specificare il numero di cifre da conservare. Nei tuoi esempi questo sarebbe 3, ma non è valido per tutti i valori:

BigDecimal rounded = value.round(new MathContext(3, RoundingMode.HALF_UP));
System.out.println(value + " -> " + rounded);

(Nota che gli BigDecimaloggetti sono immutabili; entrambi setScalee roundrestituiranno un nuovo oggetto.)


1
Non funziona: 100.12: 100.12, 100.44: 100.44, 100.50: 100.5, 100.75: 100.75
Boris Pavlović

3
No, l'impostazione della scala restituisce un nuovo decimale diverso dal primo. Ad esempio: BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0, RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2));stampe false
Daniel Fath

6
@ Daniel: Questo era già implicito nello snippet di codice che ho pubblicato nella mia risposta. Ora l'ho reso esplicito.
Grodriguez

RoundingModeCos'è quello? ÈBigDecimal
trilogia


10

Se vado dalla risposta di Grodriguez

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);

Questo è l'output

100.23 -> 100
100.77 -> 101

Che non è proprio quello che voglio, quindi ho finito per farlo ..

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);

Questo è quello che ottengo

100.23 -> 100.00
100.77 -> 101.00

Questo risolve il mio problema per ora ..:) Grazie a tutti.


7
Mi incuriosisce l'affermazione che il primo risultato "non è proprio quello che voglio ...". Se sei effettivamente preoccupato per la formattazione dell'output, puoi usare DecimalFormat(come in new DecimalFormat("###.00")) per gestire la conversione di un BigDecimalback to string. Fornisce "101.00"come risultato entrambi i valori che gli snippet di @Grodriquez e tu hai creato.
joel.neely

3
La seconda volta che esegui l'arrotondamento qui non è necessaria perché sai che hai già un numero intero, quindi userei BigDecimal.ROUND_UNNECESSARY invece, un po 'più chiaro secondo me.
kosmoplan

5

Ecco una soluzione terribilmente complicata, ma funziona:

public static BigDecimal roundBigDecimal(final BigDecimal input){
    return input.round(
        new MathContext(
            input.toBigInteger().toString().length(),
            RoundingMode.HALF_UP
        )
    );
}

Codice di prova:

List<BigDecimal> bigDecimals =
    Arrays.asList(new BigDecimal("100.12"),
        new BigDecimal("100.44"),
        new BigDecimal("100.50"),
        new BigDecimal("100.75"));
for(final BigDecimal bd : bigDecimals){
    System.out.println(roundBigDecimal(bd).toPlainString());
}

Produzione:

100
100
101
101


Non per approvare questa soluzione o altro, ma la input.toBigInteger().toString().length()parte sarebbe molto più efficiente utilizzando un logaritmo, qualcosa comeround_up(log(input)) + (1 if input is a power of ten, else 0)
Addison,


0

Non credo che tu possa arrotondarlo in quel modo con un singolo comando. Provare

    ArrayList<BigDecimal> list = new ArrayList<BigDecimal>();
    list.add(new BigDecimal("100.12"));
    list.add(new BigDecimal("100.44"));
    list.add(new BigDecimal("100.50"));
    list.add(new BigDecimal("100.75"));

    for (BigDecimal bd : list){
        System.out.println(bd+" -> "+bd.setScale(0,RoundingMode.HALF_UP).setScale(2));
    }

Output:
100.12 -> 100.00
100.44 -> 100.00
100.50 -> 101.00
100.75 -> 101.00

Ho testato il resto dei tuoi esempi e restituisce i valori desiderati, ma non garantisco la sua correttezza.


-2

Tu vuoi

round(new MathContext(0));  // or perhaps another math context with rounding mode HALF_UP

2
Questo non fa niente. Dalla documentazione di round: "Se l'impostazione della precisione è 0, non viene eseguito alcun arrotondamento."
Grodriguez
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.