Java BigDecimal: Redondea al valor entero más cercano


90

Necesito los siguientes resultados

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

.round()o .setScale()? ¿Cómo hago con esto?

Respuestas:


153

Puede utilizar setScale()para reducir el número de dígitos fraccionarios a cero. Suponiendo que se valuemantiene el valor a redondear:

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

El uso round()es un poco más complicado ya que requiere que especifique el número de dígitos que se conservarán. En sus ejemplos, esto sería 3, pero esto no es válido para todos los valores:

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

(Tenga en cuenta que los BigDecimalobjetos son inmutables; ambos setScaley rounddevolverán un nuevo objeto).


1
No funciona: 100.12: 100.12, 100.44: 100.44, 100.50: 100.5, 100.75: 100.75
Boris Pavlović

3
No, la configuración de la escala devuelve un nuevo decimal que no es el mismo que el primero. Por ejemplo: BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0, RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2));imprime falso
Daniel Fath

6
@Daniel: Eso ya estaba implícito en el fragmento de código que publiqué en mi respuesta. Ahora lo he hecho explícito.
Grodriguez

RoundingMode¿que es eso? EsBigDecimal
trilogía


10

Si sigo la respuesta de Grodriguez

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

Esta es la salida

100.23 -> 100
100.77 -> 101

Lo cual no es exactamente lo que quiero, así que terminé haciendo esto ...

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

Esto es lo que obtengo

100.23 -> 100.00
100.77 -> 101.00

Esto resuelve mi problema por ahora .. :) Gracias a todos.


7
Tengo curiosidad por la afirmación de que el primer resultado "no es exactamente lo que quiero ...". Si está realmente preocupado por el formato de salida, puede usar DecimalFormat(como en new DecimalFormat("###.00")) para administrar la conversión de un BigDecimalback to string. Da "101.00"como resultado para ambos valores que los fragmentos de @Grodriquez y usted crearon.
joel.neely

3
La segunda vez que redondeas aquí no es necesario, ya que sabes que ya tienes un número entero, por lo que usaría BigDecimal.ROUND_UNNECESSARY en su lugar, un poco más claro en mi opinión.
kosmoplan

5

Aquí hay una solución terriblemente complicada, pero funciona:

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

Código de prueba:

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());
}

Salida:

100
100
101
101


No respaldar esta solución ni nada, pero la input.toBigInteger().toString().length()parte sería mucho más eficiente usando un logaritmo, algo comoround_up(log(input)) + (1 if input is a power of ten, else 0)
Addison


0

No creo que puedas redondearlo así con un solo comando. Tratar

    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

Probé el resto de sus ejemplos y devuelve los valores deseados, pero no garantizo que sea correcto.


-2

Usted quiere

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

2
Esto no hace nada. De la documentación de round: "Si el ajuste de precisión es 0, no se realiza ningún redondeo".
Grodriguez
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.