Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] Arredondamento de Double e BigDecimal

Bom dia a todos

Nesta aula, foi feito um for each para aumentar o salario de todos os funcionarios, mas depois de fazer a multiplicacao, o número fica muito extenso, o que fica ruim, principalmente para testes em Junit:

    @Test
    fun testadoubleArrayOf() {
        var salarios = doubleArrayOf(1500.0, 1800.0, 2300.0)
        for (i in salarios.indices){
            salarios[i] *= 1.1
        }
        assertEquals("[1650.0000000000002, 1980.0000000000002, 2530.0]",salarios.contentToString())
    }

Eu queria saber uma maneira de arredondar essas Double.

E como extra, fazer arredondamento em BigDecimal, já que em testes de Junit eu tenho que fazer uma gambiarra para dar certo:

    private fun getValor(numero:BigDecimal):BigDecimal{
        return numero.round(MathContext.DECIMAL64).setScale(2)
    @Test
    fun transfereEntreContas(){
        contaCorrente.transfereDinheiro(BigDecimal(50),contaPoupanca)
        assertEquals(getValor(BigDecimal(50)),contaCorrente.saldoDaConta)
        assertEquals(getValor(BigDecimal(1050.0)),contaPoupanca.saldoDaConta)
    }
2 respostas

Nas aulas seguintes o professor ensinou o .toBigDecimal() e obtive um resultado melhor do que eu tava fazendo antes em relação à comparação do Junit, e não preciso mais do getValor:

    @Test
    fun transfereEntreContas(){
        contaCorrente.transfereDinheiro(BigDecimal(50),contaPoupanca)
        assertEquals("50.00".toBigDecimal(),contaCorrente.saldoDaConta)
        assertEquals("1050.00".toBigDecimal(),contaPoupanca.saldoDaConta)
    }

Mas na hora de arredondar contas de multiplicação e divisão, ele nos ensinou o setScale(2, RoundingMode.UP), mas eu não gostei da precisão dele, obtive resultados melhores com o round(MathContext.DECIMAL64).setScale(2). Um exemplo foi quando eu tentei substituir o round(MathContext.DECIMAL64).setScale(2) pelo setScale(2, RoundingMode.UP) neste código:

código original:

class Diretor(nome: String, cpf: String, salario: BigDecimal, senha:Int): FuncionarioAdmin(nome, cpf, salario,senha){
    var plr:BigDecimal = BigDecimal(0)
    override fun bonificacao():BigDecimal {
        return this.salario.multiply(BigDecimal(0.1)).add(salario)
            .add(plr).round(MathContext.DECIMAL64).setScale(2)
    }
}

código refeito:

class Diretor(nome: String, cpf: String, salario: BigDecimal, senha:Int): FuncionarioAdmin(nome, cpf, salario,senha){
    var plr:BigDecimal = BigDecimal(0)
    override fun bonificacao():BigDecimal {
        return this.salario.multiply(BigDecimal(0.1)).add(salario)
            .add(plr).setScale(2,RoundingMode.UP)
    }
}

código da classe de teste

class CalculadoraBonificacaoTest{
    private val joao = DiretorFoda("Joao", "12344545678", BigDecimal(6000.0),1234)
    private val alex = Analista("Alex", "12344545678", BigDecimal(2000.0))
    private val dinei = Gerente("Valdinei", "12344545678", BigDecimal(4000.0),1234)
    private val calculadora = CalculadoraBonificacao()
    @BeforeEach
    fun colocaPlRDoGerente(){
        joao.plr = BigDecimal(300)
    }
    @Test
    fun testaCalculadoradeTestes(){
        calculadora.registra(joao)
        calculadora.registra(alex)
        calculadora.registra(dinei)
        assertEquals("11500.00".toBigDecimal(),calculadora.total)
    }
}

E por algum motivo obtive o resultado de 11500.03. Queria saber qual seria um jeito mais preciso, e se o que eu falei está correto?

E ainda tenho dúvida sobre arredondamento em Double

solução!

Fala Murilo, de boa ?

Cara, trabalhar com numeros geralmente é meio treta assim mesmo, fazer o arredondamento então kkk

No caso, usar a classe BigDecimal é o melhor cenário, ainda que possa causar alguns problemas de imprecisão como tu conseguiu ver, acaba não existe uma bala de prata e geralmente usar com setScale(2,RoundingMode.UP) é o formato que tu mais verá nas empresas que passar que trabalham com dinheiro e usam bigdecimal... outros lugares trabalham com valor do tipo int, assim tu assume os numeros finais como sendo os centavos e depois disso é tudo inteiro, geralmente é mais tranquilo para fazer calculos, já que em tese, não tem ponto flutuante... como te disse, vai de cenário para cenário.