Eu preciso dos seguintes resultados
100.12 -> 100.00
100.44 -> 100.00
100.50 -> 101.00
100.75 -> 101.00
.round()
ou .setScale()
? Como faço isso?
Respostas:
Você pode usar setScale()
para reduzir o número de dígitos fracionários a zero. Assumindo que value
mantém o valor a ser arredondado:
BigDecimal scaled = value.setScale(0, RoundingMode.HALF_UP);
System.out.println(value + " -> " + scaled);
Usar round()
é um pouco mais complicado, pois requer que você especifique o número de dígitos a serem retidos. Em seus exemplos, seria 3, mas não é válido para todos os valores:
BigDecimal rounded = value.round(new MathContext(3, RoundingMode.HALF_UP));
System.out.println(value + " -> " + rounded);
(Observe que os BigDecimal
objetos são imutáveis; ambos setScale
e round
retornarão um novo objeto.)
BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0, RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2));
imprime falso
RoundingMode
o que é isso? ÉBigDecimal
Se eu for pela resposta de Grodriguez
System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);
Esta é a saída
100.23 -> 100
100.77 -> 101
O que não é bem o que eu quero, então acabei fazendo isso ..
System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);
Isso é o que eu recebo
100.23 -> 100.00
100.77 -> 101.00
Isso resolve meu problema por agora .. :) Obrigado a todos.
DecimalFormat
(como em new DecimalFormat("###.00")
) para gerenciar a conversão de uma BigDecimal
string de volta em. Ele fornece "101.00"
o resultado para ambos os valores que os snippets de @Grodriquez e você criaram.
Esta é uma solução terrivelmente complicada, mas funciona:
public static BigDecimal roundBigDecimal(final BigDecimal input){
return input.round(
new MathContext(
input.toBigInteger().toString().length(),
RoundingMode.HALF_UP
)
);
}
Código de teste:
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());
}
Resultado:
100
100
101
101
input.toBigInteger().toString().length()
parte seria muito mais eficiente usando um logaritmo, algo comoround_up(log(input)) + (1 if input is a power of ten, else 0)
Basta olhar para:
http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html#ROUND_HALF_UP
e:
setScale(int precision, int roundingMode)
Ou se estiver usando Java 6, então
http://download.oracle.com/javase/6/docs/api/java/math/RoundingMode.html#HALF_UP
http://download.oracle.com/javase/6/docs/api/java/math/MathContext.html
e também:
setScale(int precision, RoundingMode mode);
round(MathContext mc);
Eu não acho que você pode contornar isso com um único comando. Experimentar
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
Testei o restante de seus exemplos e ele retorna os valores desejados, mas não garanto sua correção.
Você quer
round(new MathContext(0)); // or perhaps another math context with rounding mode HALF_UP
round
: "Se a configuração de precisão for 0, então nenhum arredondamento ocorrerá."