BigDecimal Divisao

se com o seguinte código

BigDecimal parcela = new BigDecimal("10", new MathContext(2,RoundingMode.HALF_EVEN));
        BigDecimal quantidade = new BigDecimal("3", new MathContext(2,RoundingMode.HALF_EVEN));

        System.out.println(parcela.divide(quantidade,new MathContext(2,RoundingMode.HALF_EVEN)));

tenho a seguinte saida 3.3
e se trocar o 10 da parcela por 550 tenho a saida 1.8E+2
como faço para ter ao mesmo tempo pros valores 10 e 550 dividos por 3 a pressição de 1, 2, 3 casas decimais sempre.

tem alguma outra maneira para não dar
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

sem usar o MathContext como argumento do divide()

obrigado.

Ola amigo,

Se vc utilizar assim funciona:

[code]BigDecimal parcela = new BigDecimal(“550”);
BigDecimal quantidade = new BigDecimal(“3”);

    System.out.println(parcela.divide(quantidade,new MathContext(2,RoundingMode.HALF_EVEN)));[/code]

se vc precisar setar uma escala para o resultado, utilise

.setScale(2, BigDecimal.ROUND_HALF_UP));

Vc pode entender um pouco sobre a classe MathContext no link abaixo.
Mas o que acontece é esta classe não trata a precisão diretamente,
pode ser mais claro se você pensar em termos de notação científica.

http://pt.how-to.mobi/index.php?id=7539

blz, coloquei na divisao o MathContext.DECIMAL128 para não ocorrer problemas na divisao e no final .setScale(2, RoundingMode.HALF_EVEN)) para retornar o valor real com a pressisao que eu quero

ficando assim

public static void main(String[] args) {
            BigDecimal parcela = new BigDecimal("5550", new MathContext(2,RoundingMode.HALF_EVEN));
            BigDecimal quantidade = new BigDecimal("3", new MathContext(2,RoundingMode.HALF_EVEN));

            System.out.println(parcela.divide(quantidade,MathContext.DECIMAL128).setScale(2, RoundingMode.HALF_EVEN));
}

vlw!

[quote=l3ug1m]se com o seguinte código

BigDecimal parcela = new BigDecimal("10", new MathContext(2,RoundingMode.HALF_EVEN));
        BigDecimal quantidade = new BigDecimal("3", new MathContext(2,RoundingMode.HALF_EVEN));

        System.out.println(parcela.divide(quantidade,new MathContext(2,RoundingMode.HALF_EVEN)));

tenho a seguinte saida 3.3
e se trocar o 10 da parcela por 550 tenho a saida 1.8E+2
como faço para ter ao mesmo tempo pros valores 10 e 550 dividos por 3 a pressição de 1, 2, 3 casas decimais sempre.
[/quote]

Não é usando bigDecimal :slight_smile:
Dinheiro usa matemática de inteiros, não de decimais. Isto é contra-intuitivo, mas é verdade.

Ou vc usa o padrão Money (dê uma olhada aqui especialmente no método distribute )

Ou vc faz na mão com biginteger. lembre-se que tem que converter para centavos para isto dar certo.

10 / 3 = 3 + 3 + 3 + 1

10 em 3 parcelas gera uma parcela de 4 e duas duas de 3.

R$ 550,00 / 3 = R$ 183,33 + R$ 183,33 + R$ 183,33 + R$ 0,01

R$ 550,00 em 3 parcelas gera uma parcela de R$ 183,34 e duas de R$ 183,33

Não ha arrondamento nestas operações. Portanto, não ha erro.

Aproveitando, sempre tive a duvida, no caso de ter divisões e multiplicações, usa-se sempre money ou faz as contas intermediárias usando BigDecimal e converte-se no final ?

Por exemplo no cálculo de financiamentos.

[]s

estou usando padrão Money sim, mais com BigDecimal como valor encapsulado,

depois deste problema, tive outro problema, dividindo 560 por 1.86 da 301.07526881 arredondando da 301.08 e quando eu multiplicava novamente por 1.86 para retornar o 560 dava 560.01, o problema tava no MathContext passado na divisão, consegui resolver passando o MathContext.DECIMAL128 na divisão e no retorno usando o setScale(2, RoundingMode.HALF_EVEN),

no sistema que trabalho ele usa Double para cálculos, e nos últimos tempos depois de algumas mudanças não esta mais fechando calculo de parcelas, por causa dos arredondamentos e estouro do double nas operações com casas decimais, dai criei a classe no padrão money e fui usando ela nas rotinas de cálculos mais sempre retornando Double para não quebrar o sistema. ate agora isto esta dando certo, ate que tive este problema da divisão que já resolvi.

[quote=Edufa]Aproveitando, sempre tive a duvida, no caso de ter divisões e multiplicações, usa-se sempre money ou faz as contas intermediárias usando BigDecimal e converte-se no final ?

Por exemplo no cálculo de financiamentos.

[]s[/quote]

no meu caso deixei a classe Money se preocupar com todos estes detalhes, ai eu uso somente a classe money para calcular, e coloquei métodos auxiliares para receberem tipos primitivos facilitando o desenvolvimento.

[quote=Edufa]Aproveitando, sempre tive a duvida, no caso de ter divisões e multiplicações, usa-se sempre money ou faz as contas intermediárias usando BigDecimal e converte-se no final ?

Por exemplo no cálculo de financiamentos.

[/quote]

usa-se sempre o padrão money. mas repare que não se multiplica money por money ( não ha “real ao quadrado”) nem se divide e dá money. Money/money dá um fator decimal. Ou seja, conforme a operação vc vai sair do money e ir para “numero sem moeda” e é exatamente ai que está o poder da coisa. Os objetos vão representar as unidades.

No final de uma operação vc não precisa converter para bigdecimal. Vc pode usar o money end-to-end.
A unica ocasião que vc precisa converter para bigdecimal, ou double, é quando precisa usar api legadas ou de tercerios

[quote=l3ug1m]estou usando padrão Money sim, mais com BigDecimal como valor encapsulado,

depois deste problema, tive outro problema, dividindo 560 por 1.86 da 301.07526881 arredondando da 301.08 e quando eu multiplicava novamente por 1.86 para retornar o 560 dava 560.01, o problema tava no MathContext passado na divisão, consegui resolver passando o MathContext.DECIMAL128 na divisão e no retorno usando o setScale(2, RoundingMode.HALF_EVEN),
[/quote]

Mas entenda que isso é uma gambiarra. matemáticamente, depois que vc aredonda o numero não é mais o mesmo, logo não é possivel fazer a operação inversa e esperar o mesmo numero que antes. depois de obter 301.08 vc não pode multiplicar de volta. Isso não faz sentido.

A divisão de dinheiro acontece normalmente de 3 formas:
dinheiro / dinheiro = fator (por exemplo, quanto % eu ganhei de algum investimento)

dinheiro / fator = dinheiro * (1 / fator) = para saber uma percentagem por exemplo.

dinheiro / inteiro = distribuição. que é na realidade a subtração sucessiva do valor e serve para criar parcelas. Este é o item que resolve o problem

tenho 10 carros e 3 pessoas, quantos carros ganha cada pessoa. A reposta é 3 , não 4, e nem 3 e 1/3 porque carros que não são inteiros não são mais carros. Quando se divide dinheiro tem que se pensar se estamos usando um numero de fator, ou se estamos distribuido. E é ai que a classe money brilha.

Em termos matemáticos dinheiro não forma um anel.